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?
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.
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.
Related
In the bound services documentation, it says
When a service is unbound from all clients, the Android system destroys it (unless it was also started with a startService() call). As such, you don't have to manage the lifecycle of your service if it's purely a bound service—the Android system manages it for you based on whether it is bound to any clients.
However, if you choose to implement the onStartCommand() callback method, then you must explicitly stop the service, because the service is now considered to be started. In this case, the service runs until the service stops itself with stopSelf() or another component calls stopService(), regardless of whether it is bound to any clients.
Does this mean that simply implementing onStartCommand automagically puts the service into a started state when a client binds to it?
I've been looking for a way to guarentee that when a client binds to the service, the service is in the started state. So far, the only way I've been able to do it is by having the client call startService followed by bindService. But if the above is correct, then all I have to do is implement onStartCommand and the client is free to just call bindService.
I agree that the documentation is wrong. Simply implementing onStartCommand() changes nothing. Especially because you don't implement it, you override the method, because there is already an existing default implementation of onStartCommand()
When you bind to a Service, the Service isn't technically "started", it is just bound. onStartCommand() will not be called unless something calls startService().
Can anybody explain what is difference between unbound and bound service in android and explain about intent service
Thanks
Bound Service
A service is bound when an application component binds to it by
calling bindService(). A bound service offers a client-server
interface that allows components to interact with the service, send
requests, get results, and even do so across processes with
interprocess communication (IPC).
When the last client unbinds from the service, the system destroys the
service EXCEPT If the service was started by
startService
Unbound Service or Started
A service is started when an application component, such as an
activity, starts it by calling startService(). Once started, a service
can run in the background indefinitely, even if the component that
started it is destroyed.
BUT
Most confusion about the Service class actually revolves around what it is not:
A Service is not a separate process. The Service object itself does
not imply it is running in its own process; unless otherwise
specified, it runs in the same process as the application it is part
of.
A Service is not a thread. It is not a means itself to do work off of
the main thread (to avoid Application Not Responding errors).
That is where IntentService are used.
IntentService is a subclass of Service that uses a worker thread to
handle all start asynchronous requests (expressed as Intents) on
demand, one at a time. Clients send requests through
startService(Intent) calls; the service is started as needed, handles
each Intent in turn using a worker thread, and stops itself when it
runs out of work.
hope it helps :)
Bounded services are bounded to an activity which binds it and will work only till bounded activity is alive.
while a unbounded service will work till the completion even after activity is destroyed.
a tabular difference is given in below link which is very useful for interviews
http://infobloggall.com/2014/04/15/bounded-service-in-android/
Unbound service is started when component (like activity) calls startService() method
Where As A service is bound when another component (e.g. client) calls bindService() method.
The Unbound service can stop itself by calling the stopSelf() method.
Where As The Bound service cannot be stopped until all clients unbind the service.
The Unbound service runs in the background indefinitely.
Where As The Bound service does not run in the background indefinitely.
The Unbound service is stopped by stopService() method.
Where As In The Bound service, The client can unbind the service by calling the unbindService() method.
Thanks
Bound and Unbound Services are not two sides of a coin
A service can be a bound or unbound(started) or both, It is just the matter of implementation you provide to the callback methods of Service class. See all four callback methods here
But for the sake of differentiation here you go
1. Staring a service
Unbound Service is started by calling startService() method.
Bound Service is started by calling bindService() method.
However in both calls system calls onStartCommand() method internally
2. Life Span of a service
Once an unboundService is started it runs indefinitely until
Application component calls stopService() method
Service itself calls SelfStop() method.
BoundService runs as long as the service is bound to a client. When there is no active client bound with the service, the system destroys the Service
3. onBind() method
When you are writing a service you will have to override the onBind(). If
Unbound Service then return null
BoundService then return IBinder object.
Though unbound services does not return Ibinder object it does not mean that it can not interact with application component.
There are ways to do that for example BroadCastReceiver or ResultReceiver
One way vs Two-way communication with Service
When you want two-way communication with your Service then you should bind your service with Activity.
Eg. Playing music in the background with pause, play option (Activtiy <-> Service).
Go with unbound or started service when you just want your Service to update your Activity (Service->Activity).
Eg: Timer Service which updates Activity every second.
Another example
You have written some Service which deals with Location changes.
If you want to update your activity when you move 10 meters (Go with unbound service).
If you want to see the coordinates of your current location when you click some button in the activity. (Go with the bound service).
Is it possible to run startService() or bindService() from a Service to another Services?
startService() can be used even if you call this method inside a Service. So, it's possible to trigger another Service from the current Service. But you can't call bindService() to trigger another Service, it requires an activity to be bound and display the result in UI, such as MP3 Player. Once an activity which calls bindService() was destroyed, the bound-service will be killed by system.
Can anybody explain what is difference between unbound and bound service in android and explain about intent service
Thanks
Bound Service
A service is bound when an application component binds to it by
calling bindService(). A bound service offers a client-server
interface that allows components to interact with the service, send
requests, get results, and even do so across processes with
interprocess communication (IPC).
When the last client unbinds from the service, the system destroys the
service EXCEPT If the service was started by
startService
Unbound Service or Started
A service is started when an application component, such as an
activity, starts it by calling startService(). Once started, a service
can run in the background indefinitely, even if the component that
started it is destroyed.
BUT
Most confusion about the Service class actually revolves around what it is not:
A Service is not a separate process. The Service object itself does
not imply it is running in its own process; unless otherwise
specified, it runs in the same process as the application it is part
of.
A Service is not a thread. It is not a means itself to do work off of
the main thread (to avoid Application Not Responding errors).
That is where IntentService are used.
IntentService is a subclass of Service that uses a worker thread to
handle all start asynchronous requests (expressed as Intents) on
demand, one at a time. Clients send requests through
startService(Intent) calls; the service is started as needed, handles
each Intent in turn using a worker thread, and stops itself when it
runs out of work.
hope it helps :)
Bounded services are bounded to an activity which binds it and will work only till bounded activity is alive.
while a unbounded service will work till the completion even after activity is destroyed.
a tabular difference is given in below link which is very useful for interviews
http://infobloggall.com/2014/04/15/bounded-service-in-android/
Unbound service is started when component (like activity) calls startService() method
Where As A service is bound when another component (e.g. client) calls bindService() method.
The Unbound service can stop itself by calling the stopSelf() method.
Where As The Bound service cannot be stopped until all clients unbind the service.
The Unbound service runs in the background indefinitely.
Where As The Bound service does not run in the background indefinitely.
The Unbound service is stopped by stopService() method.
Where As In The Bound service, The client can unbind the service by calling the unbindService() method.
Thanks
Bound and Unbound Services are not two sides of a coin
A service can be a bound or unbound(started) or both, It is just the matter of implementation you provide to the callback methods of Service class. See all four callback methods here
But for the sake of differentiation here you go
1. Staring a service
Unbound Service is started by calling startService() method.
Bound Service is started by calling bindService() method.
However in both calls system calls onStartCommand() method internally
2. Life Span of a service
Once an unboundService is started it runs indefinitely until
Application component calls stopService() method
Service itself calls SelfStop() method.
BoundService runs as long as the service is bound to a client. When there is no active client bound with the service, the system destroys the Service
3. onBind() method
When you are writing a service you will have to override the onBind(). If
Unbound Service then return null
BoundService then return IBinder object.
Though unbound services does not return Ibinder object it does not mean that it can not interact with application component.
There are ways to do that for example BroadCastReceiver or ResultReceiver
One way vs Two-way communication with Service
When you want two-way communication with your Service then you should bind your service with Activity.
Eg. Playing music in the background with pause, play option (Activtiy <-> Service).
Go with unbound or started service when you just want your Service to update your Activity (Service->Activity).
Eg: Timer Service which updates Activity every second.
Another example
You have written some Service which deals with Location changes.
If you want to update your activity when you move 10 meters (Go with unbound service).
If you want to see the coordinates of your current location when you click some button in the activity. (Go with the bound service).
How is the "bind" action of the onBind() method different than just calling onStartCommand() ?
onStartCommand()
"The system calls this method when another component, such as an activity, requests that the service be started, by calling startService()."
onBind()
The system calls this method when another component wants to bind with the service (such as to perform RPC), by calling bindService().
I want to write a chat client service which receives messages from multiple users. Which function would be more appropriate?
The first (onStartCommand()) is called when your Service begins to do its work. onCreate() has completed and it is ready to get to doing what needs to be done.
The second (onBind()) is called when another Thread registers to connect to the Service so that they can communicate. You would configure or set up the means for the communication in here such as Interface validation or calls back to the registering Activity.
Binding allows you to tie the Service to the lifespan of, for example, an Activity. If the Activity completes then the Service is allowed to be released and can itself finish. The Service will last as long as there is something still bound to it.
onStartCommand() and onBind() are callback methods of Service class.
onStartCommand() called after onCreate() method of Service class first time.Next time whenever any other android component start same service then Service received new request in onStartCommand() method.
onBind() called when another Android components try to connect with already running Service by using bindService() method .Its used to pass some new info to service or try to make Service connection.
A bound service will end when it has no more activities bound to it. Binding also allows you to send additional commands to it via interfaces like AIDL. In your case, I think you'd want a bound service, as you likely don't want the service to outlive the activity.
In fact, if a component calls bindService() to create the service and onStartCommand() is not called, the service runs only as long as the component is bound to it. After the service is unbound from all of its clients, the system destroys it. So, by onBind() if the activity destroy your service would not trigger.
According to the official documentation,
when a service is started using bindService()
if a component(i.e Activity) calls bindService() to create the service and onStartCommand() is not called, the service runs only as long as the component is bound to it. After the service is unbound from all of its clients, the system destroys it.
and when a service is started using startService()
If a component starts the service by calling startService() (which results in a call to onStartCommand()), the service continues to run until it stops itself with stopSelf() or another component stops it by calling stopService().