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.
Related
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
More concretely: Is it safe to place the canceling of a task in onDestroy? Also, is it safe to use onDestroy for unregistering receivers and freeing up resources?
My aim is to make sure that my task is canceled/destroyed when the Activity is destroyed, but not before.
onDestroy():
is called when the activity is destroyed and resources must be
released.
is NOT called when the activity is destroyed in a hurry (when the
system is low on resources etc).
The first case is clear: I do all cleaning in onDestroy and no problems arise. The second case is a bit of a problem though. When the Activity is destroyed and onDestroy is skipped (so I don't cancel my task), could it happen that the task continues execution, then completes and tries to update the dead Activity, so the app crashes?
We come to the real question:
When an Activity is killed and onDestroy is skipped, is everything attached to that Activity automatically destroyed? (Is onDestroy skipped only in case that everything will be wiped out altogether? Tasks, registered receivers etc)
If onDestroy is skipped does this mean that the whole app is being killed?
Let's focus on onDestroy(), because the solution is not in onPause() or onStop(). Arguments:
onStop() could be skipped when the Activity is being destroyed, just like onDestroy
onPause is called too early and too often, so it is not appropriate for the use case. Examples:
Screen lock: onPause can be called when the device screen is locked. Very often this happens like a screensaver and the user unlocks immediately because he is standing there looking at the screen. Canceling tasks and stopping everything my app is doing in such a case will only degrade user experience. I don't want my app to choke and misbehave just because of an incidental "screensaver".
In an example app I have two screens that are Activities. The user can quickly switch between them. In this app users tend to switch screens often and quickly.
Navigation: One of the screens has a map which receives location updates from the system. It records a precise graphical log of the changes in location (route), so it needs to run constantly until the Activity is closed. Normally I would register and unregister any receivers in onResume and onPause. However, this would make the app very unusable, as the updates on the map will stop every time the user navigates away. Therefore, I would like to unregister the receivers in onDestroy.
Loading list: The second screen has a list that shows data from a webservice. It takes 4 seconds to download the data. I use an AsyncTask and I know I should cancel when necessary. It should not be canceled in onPause, because it should continue loading while the user switches between screens. Therefore, I would like to cancel it in onDestroy.
There can be many more examples. Some of them might not be totally appropriate in everyone's opinion (you might even suggest using a service instead of AsyncTask). But the idea is important, and all of them have the same idea: keep on doing work that's specific to the Activity, while the Activity is paused, but ENSURE to stop doing it when the Activity is destroyed. (It does not matter whether I am using an AsyncTask or a Service. In either case, the work should be stopped when the Activity is destroyed.)
P.S. If the answer is that it is not safe to do the clean up in onDestroy, this would mean that the Android framework requires us to stop everything we are doing in onPause. And then I would not see any reason for using onDestroy...
I would like to refer you to this baby: http://developer.android.com/reference/android/content/ComponentCallbacks2.html#onTrimMemory(int)
Essentially it gives you all the places where the system finds it useful to cancel tasks and clean its memory:
Please take a closer looks at the following 2 cases:
TRIM_MEMORY_UI_HIDDEN - the process had been showing a user interface, and is no longer doing so.
TRIM_MEMORY_COMPLETE - the process is nearing the end of the background LRU list.
Which are the cases for most of what you asked.
In the same method you can also catch TRIM_MEMORY_RUNNING_CRITICAL which will alert you to a case where the system has no memory and special actions must be taken immediately.
This method has made my development life much better in similar cases.
If you just need to do some cleanup, no matter how the activity is closed, you should be able to use a combination of onSaveInstanceState() and onDestroy(). One of those should be called no matter what. Maybe have a boolean cleanupDone in your activity, which is set whenever one of the two finishes.
Concerning saving of user data, have a look at Saving Persistent State:
Google suggest a
"edit in place" user model
That is: save as soon as the user creates new data, at the latest in onPause(). This does not mean that you need to recreate the data in onResume(), just that it should have been saved.
By the way: onStop() can be skipped only on pre-Honeycomb devices, that is, as of June 2015, less than 6 % of all devices. Still, onSaveInstanceState() should be called if either onDestroy() or onStop() are omitted.
As far as I gone with android,
1 When your apps crashes every resource relevant to it are destroyed.
2 When the device changes configuration resulting the Activity to be destroyed and recreated.
3 When apps running in background and Android kill it due to running on Low Memory
apart from these the other callback method are called i e
1 when another Activity come in front , or your device locks ..etc
In all case according to your requirement you can release all your resources in onDestroy and cancel the Thread and Asyntask and stop all the services etc .if you want your task remain paused and alive while on destroy called then you can save the configuration and retain it while onCreate is called again by check is null or not.
Android documentation says (in http://developer.android.com/training/basics/activity-lifecycle/stopping.html):
In extreme cases, the system might simply kill your app process without calling the activity's final onDestroy() callback, so it's important you use onStop() to release resources that might leak memory.
Sounds like it is wrong. How could killed process leak memory?
Suppose you started a service in your onStart() method, and you intend to stop that service when the user gets out of the Activity.
If you put the code to stop the service in onDestroy(), that code may never get called, which can leave that service running until Android decides to kill it (which may not happen for a while, if ever). That running service is and example of leaking memory/resources outside your application.
You should put cleanup code like that in a method that is guaranteed to be called.
Note that a process is killable after onPause() has been called, so onPause() is really the place you want to do cleanup that absolutely must happen.
(See table 1 in https://developer.android.com/guide/components/activities.html for details on the Activity lifecycle)
Another thing that might be really bad to leak: Bluetooth discovery or location reporting (GPS or network-based) turned on but not off as soon as possible - very bad for battery life.
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.