Service exiting after last client unbinds, even though startService() called beforehand? - android

I have an app that has a client Activity and a long-running Service. The Service may be started by the alarm manager or by the Activity itself.
The alarm intent calls startService(). The Activity calls startService, and then binds itself to the service so it can get information from it.
When I back-button out of the Activity, onDestroy() is called on the Activity, the Activity unbinds from the Service, and onDestroy() is called on the Service.
I was under the impression that if I called startService(), then the Service would stay around until stopService()/stopSelf() was called, no matter what clients have unbound from it.
Am I misunderstanding something?

It partly depends on the SDK version you are using. In this Service Lifecycle reference, it says onStartCommand() must return START_STICKY for the behavior you want. Prior to API level 5, there was no onStartCommand and services were all sticky.

Related

Are Android Service instances reused?

Is a new instance of a Service created each time the service is triggered, or are instances re-used? E.g. multiple calls to:
context.startService(new Intent(context, MyService.class));
The docs imply that service classes can be re-used:
If someone calls Context.startService() then the system will retrieve the service (creating it and calling its onCreate() method if needed)
However, I cannot find this issue addressed directly anywhere.
Once a service is started via startService() it is considered to be running. It remains in that state until:
something calls stopService()
the service calls stopSelf()
the process is terminated (e.g., Force Stop in Settings)
While running, subsequent calls to startService(), for the same service class, go to the same instance.
Bear in mind that Service subclasses that you use may call stopSelf(). For example, IntentService calls stopSelf() if, after calling your onHandleIntent(), there is no more work to be done for that service (i.e., nobody else has called startService() to send a fresh command in the interim).

What does it mean "Do not recreate the service, unless there are pending intents to deliver."?

I handle Service and the return code: START_NOT_STICKY. I do not want to restart the service.
But documentation says "Do not recreate the service, unless there are pending intents to deliver."
Could you give me an example of these pending intents that cause restarting the service?
When you return START_NOT_STICKY, this means the following:
If Android kills the process hosting your Service (which it can pretty much do at any time if it needs the resources or if it thinks your Service isn't doing anything useful), the following happens:
If your process is killed after onStartCommand() is called, but before onStartCommand() has completed, Android will restart your Service and call onStartCommand() again, redelivering the Intent that was being processed when the process was killed
If your process is killed after onStartCommand() has completed, Android will only restart your Service if there are pending Intents for your Service. In this case a pending Intent would exist if any component called startService() for your Service and that call has not yet been completely processed by your Service. This could be the case, for example, if a component called startService() while your Service was dead. Or it could happen if a component called startService() while your Service was still in the onStartCommand() method (processing a previous call to startService()).

Stopped Foreground Service Restarting Itself

I have a foreground service in which I register for location updates, and intent filter for the battery intent Intent.ACTION_BATTERY_CHANGED, and a LocalBroadcast. All of these I remove in the onDestroy of my service as once this service is dead.
I also have changed the return integer in the onStartCommand from START_STICKY to START_NOT_STICKY but this has no effect.
I log when this service is started and destroyed as well as my main activity and it seems that this service just starts on its own without any activities.
The issue is it's a foreground service so a notification accompanies it. This means that when it's started up again randomly, the user sees the notification and I don't want the service to be running on its own accord.
So to recap.
- It is a bound, foreground service.
- I return START_NOT_STICKY in onStartCommand
- When I no longer need it and close the app, I unbind from it, call stopService and the service's onDestroy is called which is where we unregister all of the receivers.
- The service is randomly started after this.
Since you use a foreground service, you should call stopForeground method
"Caution: The integer ID you give to startForeground() must not be 0."
There are only two ways to start a service, either binding or start it from a context, you must make sure you aren't doing it inside your code.
Maybe you should check on the service lifecycle:
http://developer.android.com/images/service_lifecycle.png

Difference between onStartCommand() and onBind()

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().

If android restarts a Service is onCreate called again?

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

Categories

Resources