Search code examples
androidbindingandroid-fragmentsandroid-activityandroid-service

Delay between bindService() and onBind() when starting a Service


I'm facing a strange problem with my app. I have a LocationService that runs in the background. The way I manage its lifecycle is:

  1. In onResume, every activity uses bindService(intent,serviceConnection, BIND_AUTO_CREATE) like that the service is automatically created when needed.
  2. In onStop, every activity uses unbindService(serviceConnection)
  3. This works because when switching activities, the new Activity onResume is called before the old Activity onStop method

The problem I have is, lets say I start from the home screen and I launch the app with an Activity that has a fragment in it. The order of the function call is as follows

  1. Activity onCreate --> setContentView is called here
  2. Activity onResume --> here bindService is called and should create the Service
  3. Fragment onResume
  4. Service onBind method is called

My question is why is there a something else between my bindServiceand onBind calls?? I have a feeling this has something to do with threading issues.


Solution

  • Well, this isn't a very good answer, but why wouldn't there be something else between your bindService() and onBind() calls? You seem to be assuming that when you call bind the system will immediately create and start your service, and no such guarantee is provided.

    You haven't indicated whether yours is an IntentService, or just a regular Service, and this might affect the speed with which your service is launched, but my answer would be the same.

    Also, I'm assuming that your ServiceConnection object is called, as expected, sometime after your service's onBind() returns.

    I say this not based on having read anything definitive, but because I had a similar experience: I was surprised and annoyed at how long it took before my service was created and my ServiceConnection was called, even though I returned from the service's onBind very quickly. (My fragments needed data from the service to create the initial UI so any delay in the creation of the service meant a delay in displaying the initial UI to the user.)

    In the end I settled upon launching my service using an Intent rather then a bind, e.g.

    Intent si = new Intent( this, com.company.MyService.class );
    si.setAction( MyService.SVC_BIND );
    startService( si );
    

    I then sent MyService.SVC_UNBIND in place of calling unbind. When I received the UNBIND intent in my service I cleanup and then call stopSelf(). These are user actions - I just named them for how I'm using them.

    I believe this was faster, but looking back upon my comments from that code I don't have any specifics. Note that this meant no ServiceConnection, but I'm making some direct calls from the activities into the service, and using LocalBroadcastManager a fair bit.

    Another option to consider (in order that your service be started more quickly, if that is your goal here??) is to launch it in Appliction.onCreate(), rather then waiting for Activity.onResume(). All of these options make it necessary to do some extra work to determine when to stop the service, compared to your current, normal, scheme where that is taken care of for you.