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.
Related
I'm writing an app which has a long-running service.
I've written some state-saving code in the service's onDestroy method.
My intention is that this should be invoked if the service ever gets killed by Android, due to memory pressure.
How can I simulate the service being killed by memory pressure?
I've tried adb shell am force-stop com.example.app but the service's onDestroy method was not invoked.
Is onDestroy a sensible site for service-shutdown-state-saving?
If so, how can I make a service's onDestroy be invoked by Android, for debugging/testing purposes?
You should not rely on onDestroy() because it only gets called, when service is properly stopped (by calling stopService() or stopSelf() method).
If you want to save service state, you should either save it as you go (for instance a player service can store it when play/pause function is activated), or use a timer to save it periodically.
If you want to react to memory events, you should use ComponentCallbacks2 class, which will notify you, when Android needs more memory. If you free memory inside those callbacks, you will increase probability your service will stay in memory longer.
Hope this helps.
If you want to programmatically stop your Service, within the Service, call stopSelf().
Alternatively go to the app settings and do a force stop.
A force stop will not call onDestroy on any components, neither service nor activity. It completely closes the app without any further considerations.
I'm not sure about this but if your service isn't running as foreground service you can close it by removing the app from recent apps menu.
I have a doubt that if i start a periodic service using alarm manager and start the service from the onCreate method of an activity. How can i prevent the service from triggering multiple times if that activity is launched again and again.
Assuming that you are creating a Normal Service (and not an IntentService), as per the Android Service documentation, when app invokes startService call, service will be instantiated and started (creating a process for it if needed).
Also, if it is running then it remains running.
So, to put it in simple terms,
Life cycle of "Started" service is independent of the life cycle of
Activity which has started this service. This is true irrespective
weather both are running in same process or different processes
So even though your Activity may be getting created multiple times, and if Service you created earlier is still running, then service object that already exists will be reused.
However, if there is a call to startService() from onCreate() of an Activity, this will invoke each time onStartCommand().
Hence, you need to ensure that you have a appropriate code/logic to handle multiple invocations of onStartCommand()
As far as I understood you must do something in either onCreate/onStart and onStop or onResume and onPaused. By do something I mean, in onCreate create what you need, alarm manager, etc then in onStart you can start the service and in onStop you stop the service or unBind from it, in case you want a foreground service. or in onResume or onStop.
Take a look here:
https://github.com/toaderandrei/live_tracking/blob/master/app/src/main/java/com/ant/track/activities/ServiceConnectActivity.java.
It is a tracking app that is based on MyTracks app from google.
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.
When an Android app is forced closed (System.exit(0)) or it crashes, the service associated with it, running in the background is not destroyed. In simple words, the onDestroy() method of service is not called. Because of this when the android app is restarted, the service starts up again ( its onCreate() is called right away). I want to avoid this.
So, the question is :
How Can I Destroy the background service in such a case as I don't have access to its onDestroy()?
If you are extending a regular plain Service class, then what you say won't happen. I think you are starting a thread for your service. If that's the case, then make sure you call stopService with the right intent to close the running Service. I am assuming your Service is a started service type and not binding type.
My application consists of one activity which creates a service. I want the service to be keep running as long as application is running. I know:
It is not guaranteed as Android system can kill activity in low memory conditions and if activity is in background.
The service can be stopped (and killed) by system.
If I bind service to the activity, the activity would get notification in case service is being stopped or started. However, the service may stop running if activity goes in background (onStop()). Please correct me if I am wrong here.
If I bind to service in onResume() of activity and unbind() in onStop(), it might happen that service stops running when my application goes in background. If I bind in onCreate() and unbind() in onDestroy() of activity, would it mean that my activity will keep getting notification from service even when in background.
What is the best way to keep service running and get notification from service to Activity as long as application is running. Please note that there is just one activity in the application so sending activity in background means application goes in background.
Thanks
true
true, but its more rare if us use startForeground()
The service usually won't stop until all activities have unbound. But when the last has, it will. So u can prevent the service from dieing when going to background, if you only unbind in onPause if isFinishing() == true.
see 3.
I personally like to set up a Handler in the Activity and send Messages to it from the service.
If you are binding a Service to your Activity. It simply means that you need service to run as long as your activity is running. If you do not need to bind Service with activity or you do not need to update your UI while your Service is running. you must not bind your Service to your Activity. In this case, for different actions done by Service you can notify user using Android Notifications. Like notifying user that xx download has been completed.
It totally depends upon your purpose that you want to achieve from Service.
if you can use IntentService for your application, you can pass data to the service through an Intent. results can be passed back to the Activity through a ResultReceiver
If you bind your Service to your unique Activity, you'll have it alive as long as the Activity is not terminated or the service isn't unbound. Just bind it on the onCreate() and let it get unbound when stopping your activity (no need to do anything).
You can create a Listener interface within your service, that you'll implement in the Activity, so you can send those notifications from the Service to the Activity. You'll find suitable example and information about this if Googling.