Through Android's Activities doc, it is said that the methods onStop() and onDestroy() are not guaranteed to be called.
[...] once the activity is created, onPause() is the last method that's guaranteed to be called before the process can be killed—if the system must recover memory in an emergency, then onStop() and onDestroy() might not be called [...]
I would like to know, when this situation occurs, is the app also killed within the activities or just the activity itself is killed?
Answer is app process is also get killed and can be recreated.
https://developer.android.com/training/basics/activity-lifecycle/recreating.html
Please check http://www.vogella.com/tutorials/AndroidLifeCycle/article.html
Application with only stopped activities and without a service or executing receiver. Android keeps them in a least recent used (LRU) list and if requires terminates the one which was least used.
Related
I am not clear on what the situation is when an activity is "destroyed" by the OS.
Let me explain why - in the diagram of the activity lifecycle here: http://developer.android.com/reference/android/app/Activity.html
There is an arrow going directly from onStop() to 'App process killed' then an arrow from 'App process killed' to OnCreate().
This diagram therefore shows that onDestroy() is NOT called if the OS kills the activity due to memory constraints etc.
However in the description of the lifecycle the word "destroy" is used many times. For example the following quote from this page: http://developer.android.com/training/basics/activity-lifecycle/recreating.html
The system may also destroy your activity if it's currently stopped
and hasn't been used in a long time or the foreground activity
requires more resources so the system must shut down background
processes to recover memory.
So the documentation is saying the activity is destroyed yet in the diagram the arrow goes from onStop() to onCreate() and bypasses onDestroy(). This is why I am confused as it is apparently a contradiction.
If I have an activity which creates some objects in its onCreate() method and I set them to null in onDestroy() but onDestroy() is not called if the app moves from onStop() to onCreate() then won't I have a memory leak as they will get created again in onCreate()?
I can't set them to null in onStop() because then if the lifecycle moves from onStop() to onRestart() to onStart() they will be null.
Therefore how does one deal with the correct sequence of creating and destroying of child objects within an activity in order to deal with all paths in the lifecycle diagram?
Is it necessary within onCreate() to only create the objects if they are null and not otherwise?
This diagram therefore shows that onDestroy() is NOT called if the OS kills the activity due to memory constraints etc.
The arrow in question is labeled "Apps with higher priority need memory". Hence, this diagram shows that onDestroy() is not called if the OS terminates the process because apps with higher priority need memory. Android will terminate the app's process more gently in other cases, and in those cases, Android will take the time to call onDestroy() on your activities. onDestroy() is also called in other scenarios, such as finish(), the default behavior of the BACK button, the default behavior on a configuration change, etc.
If I have an activity which creates some objects in its onCreate() method and I set them to null in onDestroy() but onDestroy() is not called if the app moves from onStop() to onCreate() then won't I have a memory leak as they will get created again in onCreate()?
No, because the whole process is terminated "if the app moves from onStop() to onCreate()". Android does not destroy individual activities due to low memory conditions, despite some statements in the documentation to the contrary.
Therefore how does one deal with the correct sequence of creating and destroying of child objects within an activity in order to deal with all paths in the lifecycle diagram?
Lots of things should be cleaned up in or before onStop(). Specifically, anything that you're doing that may cause the user to regret having installed your app, such as requesting GPS fixes, should be considered for cleanup in onPause() or onStop().
For those things that you determine properly should be cleaned up in onDestroy(), do so. AFAIK, there are only three possibilities:
You are called with onDestroy() and can do your cleanup work
Your process is terminated, in which case your cleanup work is no longer needed or possible
You crashed with an unhandled exception, in which case Android is not guaranteed to call any more lifecycle methods (moral of this story: use good exception handlers)
I am wondering that will activity run the method "onDestroy" when killed by system?
for example, when the state of "activity A" is onStop ( user may press the Home button directly ),
at the same time, system find out that the memory is not enough so system have to kill some background processes to keep foreground activity alife, say system kill activity A.
Will activity A run the method "onDestroy" in this situation?
It will purely depend on the system condition at that time. Docs clearly says about onDestroy() that:
There are situations where the system will simply kill the activity's
hosting process without calling this method (or any others) in it, so
it should not be used to do things that are intended to remain around
after the process goes away.
See Here
From the developer.android.com :
When your activity receives a call to the onStop() method, it's no longer visible and should release almost all resources that aren't needed while the user is not using it. Once your activity is stopped, the system might destroy the instance if it needs to recover system memory. 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.
So, android usually will call onDestroy() of your activity before it is killed but it is not guaranteed.
Link : http://developer.android.com/training/basics/activity-lifecycle/stopping.html
Depends, as when system kills an application, it's associated PID killed by it directly. As Android is nothing but Linux, it sends SIG9 (9 number signal is "kill")/ kill (Application's PID) to kill application without invoking it's callback methods.
I can't figure out the onDestroy() behaviour.
My question is: Is there any chance that an activity will be killed without calling it's onDestroy() while not killing the hole app?
I mean, Could it be that I'll get back to my app (to an activity other then the activity that the launcher calls) and be in a situation where one activity was killed without calling it's onDestroy()?
I have a need to know that if I get back from the background to an activity that there is no way some of my activities where killed without it's onDestroy.
Thanks!
No i don't think so , when your application get killed because of lack of Memory your whole app process would be killed so in this situation onDestroy() may not be called and your app will back again on your launcher Activity unless you can save your application state on onPause() state before your app get killed.
yes, Android will kill a least frequently used activity if there is not enough memory is available for the newly started app. Also the back button triggers the onDestroy(). A best bet is to save your app state. Here is an example to a similar question how to save and restore your current instance.
As stated in the API documentation Activity#onDestroy():
Note: do not count on this method being called as a place for saving
data!
http://developer.android.com/reference/android/app/Activity.html#onDestroy%28%29
And don't forget to call super.onDestroy()
I'm confused why anyone would ever override Activity.onDestroy() instead of onPause() if according to the documentation:
There are situations where the system will simply kill the activity's
hosting process without calling this method (or any others) in it,
I see much code that overrides onDestroy() despite this warning. Why?
Why override Activity.onDestroy() if it isn't reliably called?
It's not that it isn't reliably called... it's just that it isn't the only way the Activity can be killed. The Android system might trash your entire process without giving the ActivityManager the chance to call onDestroy() if your device begins to lack memory resources.
For this reason, you shouldn't ever rely on onDestroy() being called, and you should always save persistent state in onPause.
Objects held by the activity will get destroyed if the process is killed directly. If the process is not killed (and onDestroy() is called) then you will have to manually release the objects if needed. E.g, when the process is killed, a Cursor will be destroyed, but if the process is not destroyed and you repeatedly enter the activity there will be resource leakage.
The life cycle diagram of an Activity on an android does not guarantee that onDestroy() would be called, but that the process may be killed and the Activity is removed abruptly. The life cycle diagram of a Service on an android does guarantee that onDestroy() would be called. So I have two questions relating to this difference.
Firstly, if the Service is part of the same process as the Activity, is the Service onDestroy() called, though the Activity onDestroy() is not called? I would think not, as "killing a process" suggest that the operating system is stopping its threads and releasing its resources.
And if that is the case, can a Service-only-process be abruptly killed by the OS?
I'm not sure where you're seeing that a Service is guaranteed to have onDestroy() called. As far as I know, this isn't the case. If you read this page of the docs, it describes the conditions in which a service could be killed. So if you're asking if a process which hosts both an activity and service is being killed, will onDestroy() be called on the service (but not on the activity) then the answer is no; a service's onDestroy() will not necessarily be called. As to whether a service-only process can be abruptly killed by the OS: yes, it can. This is especially true when you have a lot of work to do, and your onStartCommand call only queues up the work to do asynchronously. Then the service will be spending the majority of its time not in the protected onCreate, onStartCommand or onDestroy methods.
There are two things to consider:
Android might decide to shut down a process at some point, when memory
is low and required by other processes that are more immediately
serving the user. Application components running in the process that's
killed are consequently destroyed. A process is started again for
those components when there's again work for them to do. Source
In this case onDestroy() is not called as the Android OS will reclaim resources anyway (this is a basic task of the OS in general).
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(). Source
So when the Android OS notices that the Service has finished its job and is not needed anymore it will be destroyed. The OS gives the app a chance to release the Service's resources to prevent memory leaks. In this case onDestroy() is called as this is the place where the app can release its resources. Of course in this case the application's process stays untouched (as there may be other Services/Activities running in it).