I'm trying to figure out what happens to an android service when
PowerManager.goToSleep()
is called.
Say the device is asleep for x amount of time. When the device comes out of the sleep state, there are no LifeCycle methods like onPause() or onRestart() within a service that are used to notify the service of the change.
I know that according to the documentation, all WakeLocks are overridden, so does that imply that the service will be destroyed and not started again?
http://developer.android.com/reference/android/os/PowerManager.html#goToSleep%28long%29
so does that imply that the service will be destroyed and not started again?
No. It implies that the service is unchanged. All sleep mode does is stop the CPU.
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 want my FusedLocationProvider to ping for location even when the screen is off. For this, in my service, I have a PARTIAL_WAKE_LOCK, to keep the CPU running and to ensure that the service continues to run even when the screen is off.
That being said, I know the Android OS will kill off services/apps in the background when it needs memory. Due to this, my service can be killed off.
When this happens, onDestroy() in the Service is not guaranteed to be called. If that is the case, how do I ensure that the WakeLock gets released?
I call mWakeLock.acquire(); in onStartCommand, and in onDestroy I call mWakeLock.release();
how do I ensure that the WakeLock gets released?
According to the docs:
If the service is currently executing code in its onCreate(),
onStartCommand(), or onDestroy() methods, then the hosting process will be a
foreground process to ensure this code can execute without being killed.
What this means is that if the code in any of those methods is currently being executed, then the process won't be killed (or at least will be given a very high priority) till the code finishes executing.
However, the short answer to your question is that there is NO way to ensure that onDestroy() or onPause() gets called. onPause(), though, does have a far greater probability of getting called, so you could look into that. There is also a method, Application.onTerminate() which you may want to use for further research on this. The method is only called when running the app on emulators.
I don't think you need to worry about a memory leak, though (assuming that we are both on the same page regarding what such a leak constitutes). When a process is killed, the memory is reclaimed by the kernel, not by the GC, so there isn't going to be a memory leak in that case.
EDIT:
I have confirmed that if a process is killed, an acquired wakelock will necessarily be released:
1. Does the android os release a wakelock if the app or service holding it is killed ?.
2. What happens with the partial wake lock if the process that acquires is killed ?.
3. Binders & Death Recipients.
4. How to deal with (orphaned) WakeLocks?.
I have a long running service which responds to multiple BroadcastReceivers (created in code, not manifest). Most of the time the service is running well, but from time to time it gets somehow stopped (the BroadcastReceivers stop to work) - I guess the system pauses it somehow (when I look into the running processes on the device I can clearly see the service is still "runnning").
I don't know the right reason why the service is being paused, but I'd like to know whether in these cases the onDestroy() method is called or whether there's a chance to handle this somehow.
I presume onDestroy() is not being called, because the service is still visible in the Running processes tab. I also have the service return the START_STICKY flag so the system should restart it whenever it's killed for memory reasons. Also if it is "paused" somehow, is it possible to create a WakeLock for this not to occur?
I know that the best solution would be to put all the BroadcastReceivers into the manifest and create a one shot-service called from their onReceive() methods. However I have chosen to go with the way of long running service because the initialization stage is very intensive it's better to initialize everything just once.
onDestroy() will be called only when service is being killed by lack of resources or when you explicitly stop it.
The service can be "paused" when your phone goes idle (usually when screen is off) because the CPU stops. To make services run always you should use PowerManager.PARTIAL_WAKE_LOCK - but use it wisely because it does not stop your CPU and thus draining the battery. You should never leave your apps running always. Just do what you need holding a WakeLock and then release it.
http://developer.android.com/reference/android/os/PowerManager.html
http://developer.android.com/reference/android/os/PowerManager.WakeLock.html
You can use AlarmManager to "wake" your apps periodically and do something.
http://developer.android.com/reference/android/app/AlarmManager.html
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.
What happens to android application and activities and services that belongs to application when the phone/AP goes to sleep mode?Will the framework destroy Activities and Services and OS kills the process?
In case of device sleep, activity's `onPause()' will be called. Read activity lifecycle to understand this.
OS only kills the process when memory/resources are low. Activities are killed first, services are only killed as last resort.
But there is no guarantee they will not be killed. This is why you should rely on system services to call you when you need some work done: use AlarmManager to do call your code periodically or use listeners to notify you of system changes (gps, network, etc..)
When the phone sleeps activities don't get destroyed. I believe all that happens is the activities stay the same but fire the onPause() method.
See this image:
What i saw in my application is that only the onPause() method of the main activity (category.LAUNCHER) is called. This happened when the phone went to sleep and before that the main activity of the application had been started.
When any one of the other activities had been started before the phone was going to sleep the first onPause() is called then onStop() and in the end onDestroy() - this is for activities which are category.DEFAULT into the manifest.
I don't know maybe the problem is in my code?
When the phone goes to sleep the onPause() method is called. This method is just a warning to your app. Then depending on the device the CPU may also go to sleep and execution of your code may stop. On most devices this may be anywhere from 10 to 60 seconds after the screen goes black.
It is very unlikely that going to sleep will result in your app being killed.