Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onServiceDisconnected() not called after calling Service stopSelf()

I have an Activity in which I start and bind to a download Service.

When calling stopSelf() in the Service, onServiceDisconnected() in the Activity is not called.

I would expect it to be called, since if the Service is stopped, all bound activities should be unbound.

What am I missing?

like image 441
jul Avatar asked Sep 07 '25 15:09

jul


2 Answers

According to the official document, onServiceDisconnected() would be called if the service crashed or was killed. Link http://developer.android.com/reference/android/content/ServiceConnection.html

Called when a connection to the Service has been lost. This typically happens when the process hosting the service has crashed or been killed. This does not remove the ServiceConnection itself -- this binding to the service will remain active, and you will receive a call to onServiceConnected(ComponentName, IBinder) when the Service is next running.

like image 102
Hoan Nguyen Avatar answered Sep 10 '25 13:09

Hoan Nguyen


Simply sending a notification to a bound client and calling stopSelf() (or stopService()) won't actually accomplish what you are trying to do. You have to call unbindService() in the bound client (and the service must have no other bound clients) in order to actually destroy the service.

There are two types of Services, "started" services and "bound" services. They are not mutually exclusive. If you started the service using startService(), you have a "started" service. If you start the service through bindService(), it is bound. If you bind to the service and also use startService(), it is both. So there are three possible options for managing a service's lifecycle:

1) Started Service: you call startService() to start it; service will only be stopped by calling stopService() or stopSelf().

2) Bound Service: you call bindService() and pass in the BIND_AUTO_CREATE flag. Other clients can bind and unbind to the service at will, the service will be automatically destroyed when all clients have detached. In this case, calling stopService() or stopSelf() has no effect.

3) Combo: clients bind to the service and you have also called startService(). In this case, calling stopSelf() or stopService() will only destroy the service once all clients have detached. Likewise, the service won't be destroyed automatically when all clients have detached, until stopSelf() or stopService() have been called.

The documentation for the lifecycle for combo services says:

These two paths are not entirely separate. That is, you can bind to a service that was already started with startService(). For example, a background music service could be started by calling startService() with an Intent that identifies the music to play. Later, possibly when the user wants to exercise some control over the player or get information about the current song, an activity can bind to the service by calling bindService(). In cases like this, stopService() or stopSelf() does not actually stop the service until all clients unbind.

So in your case, you have a bound client. Calling stopSelf() doesn't forcibly disconnect bound clients, so you have to explicitly notify your client that the service wants to shutdown, and then your client has to call unbindService() before the service is destroyed. You can accomplish that in a variety of ways, most simply through a broadcast or an IBinder interface, or a messenger or AIDL if you are communicating with your service across processes.

like image 21
d370urn3ur Avatar answered Sep 10 '25 12:09

d370urn3ur