I have a remote service, and I want to use the service to check some conditions in onPrepareOptionsMenu. But sometimes I got "binder null" exception when I back from other activities. I set binder to null in onServiceDisconnected.
My question:
Does onServiceDisconnected be called after activity onStop?
Is it better to bindService in onStart instead of onCreate?
Could you please explain simply the difference of local service and the remote service?
1) No. onServiceDisconnected() only gets called when the Service terminates unexpectedly, like when the process hosting the Service crashes. It will not be called when you unbind from the Service yourself. From the documentation:
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.
2) Generally, if you don't need to be connected to the Service while your Activity is stopped, then yes, binding in onStart() and unbinding in onStop() is the right way to go. The idea here is that you won't be wasting resources when your Activity is in the background. However, the documentation for bound services state that binding in onCreate() and unbinding in onDestroy() is OK too in some cases.
3) A local Service implies that the Service is in the same process as the consumer. A remote service is a Service that is in a different process.
Related
I have an Activity that binds to a service and does operations on it.
Will the Activity lose its connection to the service if it is put into the background and onStop() is called?
When the Activity is restarted, will the connection be valid?
That depends on where you call unbindService(serviceConnection).
onStop() does not invalidate an existing bind unless you explicitly call unbindService() in onStop().
Also see documentation:
If your client is still bound to a service when your app destroys the client, destruction causes the client to unbind. It is better practice to unbind the client as soon as it is done interacting with the service. Doing so allows the idle service to shut down.
I am trying to run a service in the background, despite the lifecycle state of the Activity that creates it. To guarantee it's running, the service (in addition to the services it performs) also has a thread that logs once a second. Finally, it also has logs in onStartCommand and onDestroy.
I'm starting the service with startService() and then I bind to it. My understanding is that this should keep the service running, regardless of what happens to its creator Activity. However, if the Activity is destroyed, the service stops logging. If the Activity is simply paused, there is no problem.
The following is also true:
1) onDestroy is never called on the service
2) I never call stopService or stopSelf after calling startService
I'm trying to figure out why the service is dying (there are no exceptions) or at the very least why it's being paused and no longer logging.
A bound service typically lives only while it serves application component and does not run in the background indefinitely.
http://developer.android.com/guide/components/services.html
http://developer.android.com/guide/components/bound-services.html
Use syncadapter instead of service . if you want to transfer data between server and client .
http://developer.android.com/training/sync-adapters/creating-sync-adapter.html
Android provides the Service class, which can be useful for background or non-UI operations.
I have a question about Services' lifecycle.
I know that bound services have the lifecycle like following:
Some component starts the Service via bindService() -> onCreate()
onBind()
process
The binding component calls unbindService() -> onUnbind()
onDestroy()
My question is:
Activities usually call unbindService() at onStop().
However, the Activity can be killed without calling onStop() - I mean, when the system memory is low, the only method that must be called is onPause(). onStop() is after onPause(). Before calling onStop(), the Activity can be destroyed.
In this case, the Service didn't get unbindService(), so the Service is still running. Is this right?
Of course, this rarely happens because Services are background by default. (Services are more likely to be killed by system on low memory.) However, a "Foreground" Service has higher priority than the "onPause()ed activity." according to http://developer.android.com/guide/components/processes-and-threads.html . In this case, the binding activity will be killed first.
If this thing happens, the Service does not end? If memory is not low anymore, then the Activity will be created again, but will call bindService() again since it is a new instance. Also, the Activity even may not restart. Isn't this right? What can I do in this case?
The Service is killed, but if you have 'return START_STICKY' being returned from the onStartCommand(...) [AND you are starting the service using 'startService(intent)'], the service will start back up again. The Service will start back up even if the Activity is not opened again.
I have run this example - the BoundedAudioService example and tested by killing the activity - the service restarts itself. (By restart I mean, the onStartCommand(...) of the service is called again)
A bound service typically lives only while it serves another application component and does not run in the background indefinitely.
From my little android knowledge I understand that android OS can kill my service under extreme memory conditions.
I have created a service that returns START_STICKY. The service is meant to run in background.
If android is about to kill my service, will it call onDestroy ?
And when it restarts it would it call onCreate ?
See here, the dev guide. http://developer.android.com/reference/android/app/Service.html#ProcessLifecycle
onCreate() is only called when the process starts, which can either be the first time the service is running, or if it was killed on restarted, essentially this is called whenever it starts.
onStartCommand() is called whenever a client calls startService().
When a service is destroyed / completely stopped, Android is supposed to call onDestroy() on that service. I think it's possible for that to not happen (e.g. process is killed not through Android system). In the case of a bound service, this is when there are not more active client binders.
Edit: onCreate() Service starts; onStartCommand()someone uses service; onDestroy()Service is killed / stopped.
If someone calls Context.startService() then the system will retrieve
the service (creating it and calling its onCreate() method if needed)
and then call its onStartCommand(Intent, int, int) method with the
arguments supplied by the client
...
A service can be both started and have connections bound to it. In
such a case, the system will keep the service running as long as
either it is started or there are one or more connections to it with
the Context.BIND_AUTO_CREATE flag. Once neither of these situations
hold, the service's onDestroy() method is called and the service is
effectively terminated. All cleanup (stopping threads, unregistering
receivers) should be complete upon returning from onDestroy().
http://developer.android.com/reference/android/app/Service.html
EDIT: Quick answer. Yes to both questions
I'm a little confused on how binding to services works. I understand using Context.startService() starts the service and that bindService doesn't call onStartCommand. But my understanding is that if I use startService, I have to explicitly stop the service. But I want the service to die if there are no more activities bound to it.
My problem is that calling bindService never calls onServiceConnected(), so my Service binder object is null. Does the service have to be explicitly started in order to bind to it? If so, how does it know to terminate when nothing is binding to it anymore, and how do I know if it's started so I can know to use the bound object?
if you call bindService with BIND_AUTO_CREATE as flag the system will bind your activity to the service if it exists, otherwise if it doesn't exist the system will start the service for you and then it will bind your activity to the service. Furthermore if you start a Service in this way the service will remain active only if it has still some context binded.
this is from bindService():
Connect to an application service, creating it if needed. This defines a dependency between your application and the service. The given conn will receive the service object when its created and be told if it dies and restarts. The service will be considered required by the system only for as long as the calling context exists. For example, if this Context is an Activity that is stopped, the service will not be required to continue running until the Activity is resumed
and this is from ServiceLyfecycle
A service can be both started and have connections bound to it. In such a case, the system will keep the service running as long as either it is started or there are one or more connections to it with the Context.BIND_AUTO_CREATE flag. Once neither of these situations hold, the service's onDestroy() method is called and the service is effectively terminated. All cleanup (stopping threads, unregistering receivers) should be complete upon returning from onDestroy().
The answer is that I wasn't waiting for the service to actually be bound before using it, since it gets bound asynchronously
You should be setting up your binder in onBind and any generic setup in onCreate. The behaviour of starting and binding services is explained at http://developer.android.com/reference/android/app/Service.html#ServiceLifecycle