I'm trying a simple android app that starts and stops a simple service with startService(). I notice that each time I manually terminate the app process (by closing the app), another instance of my service is created.
In other words, the service that I created isn't destroyed, and an additional service is created. I can see that the onDestroy() isn't called, and the onCreate() & onStart() get called again
Why is that? How can I prevent it? You can see the source code I'm using in this example: Source Code
If you start your Service using Context.startService() and your Service returns START_STICKY from its onStartCommand() then the system is expecting the Service to either be explicitly stopped via something calling Context.stopService() or the Service itself calling stopSelf(). When you use the Recents screen to "swipe away" your app, you are forcefully killing the process but not explicitly stopping the Service.
Related
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.
I execute stopSelf as service finishes working (from within service) but it is not destroyed (see using log output in onDestroy()) right after it. It leads that startService uses existing (stopped) service instead of starting new one. How can i force service to be destroyed right after it is stopped?
From Documentation:
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.
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
My android application starts a service in the onCreate() callback of a class that extends Application. The service performs some background tasks that are relevant to the user only while the application is running. For that reason I would like to close the service when the application's last activity is closed. I've tried to perform closing the service in the callback onTerminate() , but it never gets called . So what would be the best place where a service should be closed ?
Thanks !
An Android service, once started, will continue running until the Context.stopService() or stopSelf() is called.
There are various hooks you can use to stop the service using Context.stopService (the service itself, or an onDestroy()/onPause callback in one of the activities, or a button click).
It's true that Android does some resource management itself, but it can take a long time before Android decides to terminate your services. And a service that's running but not doing anything just consumes resources on the phone that other apps might need.
In your case, the onPause method of your last activity would be a good that will get called, and as such is the correct place to stop the service.
The onPause() callback will be made when your activity is paused for any reason, and you know that when this happens your app will not be visible again until onResume() is called. If your service has a reason to run in the use case that your activity might be started again soon, you should add an entry to your service that onPause() calls, to set a delayed service termination. In onResume() you can cancel that delayed termination through another entry.