I've got a Service, that starting with BOOT_COMPLETED. This Service periodicaly sends GPS data to the server. Sometimes OS kills this Service in the wake of memory, but onDestroy() method of Service didn't called. Where can i put some values for saving and restoring when my Service is restarted?
Simple put: You can't with the regular service lifecycle events.
If the onDestroy() method is not called the system killed the process the hard way, without terminating it properly. As there is no event for that you have to use other callbacks to detect a possible kill situation.
The only possibility which could help is to listen to onTrimMemeroy or onLowMemeroy although these callbacks do not mean that your service will be killed it might help as an indicator when you should save your data.
More can be found here: http://developer.android.com/reference/android/content/ComponentCallbacks2.html
For reference, here is the lifecycle of a service if terminated properly:
You can ovveride the onTrimMemeroy() and onLowMemeroy() method to handle this problem, the detailed illustration about these two method that you can get from here
Related
I would like to issue broadcast when service goes down. What callback is guaranteed to run when this happens? I want other apps to know its down, I cannot take a chance that it goes down and no one knows about it. So at point in the service lifecycle (which method) should I issue the sendBroadcast(ImGoingDown)? For example, how soon would onDestroy() be called?
While most answers here are aiding in the onDestroy approach, there are many events on your service being destroyed that you cannot intervene. For instance, if the user has force closed your application, your service is destroyed, but onDestroy will NOT be executed.
On a common scenario, your service would be destroyed when it has ran out of operations (mostly know as finished), when no other process that are bound to the service, or when its stopSelf()is executed, and most common, when the device is running low on RAM.
onDestroy would be the scenario where you can restart it.
As a suggestion, if the device has killed your process due to low RAM, dont restart it right away. set a Handler or AlarmManager to start it a bit later (so the lack of memmomry dont execute in back again.)
You can fire the broadcast in onDestroy(). This is the last call the service receives before getting destroyed. Service lifecycle ends with this call.
If you are running a background service that means you must be doing something in background, sending broadcast from onDestroy() might not be a best practice.
Think, your service gets destroyed because the task you wanted to run is completed, then you might don't want to send a broadcast in that case. You want to send a broadcast only when the service is killed right? So the better approach is to setting a boolean, say isTaskFinised, and if it returns false only then your onDestroy() should send a broadcast.
#Override
public void onDestroy(){
if(!isTaskFinished){
//send a broadcast
}
}
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've got some methods in onDestroy in my service. They must be called to set some application settings. Maybe there is a possibility to receive some kind of broadcast to set the settings values? As I understand, this service won't be active after the system reboots. Any ideas?
I've got some methods in onDestroy in my service
onDestroy() is not guaranteed to be called on a service. For example, if the user force-stops you from Settings, or you crash with an exception, or Android needs RAM in a hurry and terminates your process, onDestroy() is not called.
They must be called to set some application settings.
Then you should be calling them sometime other than onDestroy().
Maby there is a possibility to recive some kind of broadcast and even set the settings values?
You can try having your service listen for the ACTION_SHUTDOWN broadcast, but that will not solve your problem, as there are other scenarios in which onDestroy() will not be called, as noted above.
As I anderstand, this service when the system reboot won't be active
Correct.
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.