This is about POST-honeycomb (i.e., Android 3.0+) and the quotes below come from https://developer.android.com/reference/android/app/Activity.html
According to the lifecycle, onStop and onDestroy are killable, this means:
Note the "Killable" column in the above table -- for those methods that are marked as being killable, after that method returns the process hosting the activity may be killed by the system at any time without another line of its code being executed
In other words, onStop (along the others that occur before this event) is guaranteed to be called, yet at the moment the method returns, the process might die, thus onDestroy is not guaranteed to be called.
Another quote states:
For those methods that are not marked as being killable, the activity's process will not be killed by the system starting from the time the method is called and continuing after it returns.
Followed by
Thus an activity is in the killable state, for example, between after onPause() to the start of onResume().
But this does not correspond to what was said above, unless this only corresponds to PRE-honeycomb. This is not true for POST-honeycomb, right? So basically, both onPause and onStop are guaranteed to be called.
Assuming I only release a resource in onDestroy, then this might lead to a possible leak since onDestroy might not be called, right?
However, can this scenario (i.e., onDestroy is not called) occur besides when the process is killed by android itself? Are there any other scenarios that cause onDestroy not to be called, thus leaking the resource.
Is it true that when Android kills the process that the resources will be destroyed and no leak can occur (even when we did not explicitly released the resource?).
Please provide detailed information whether those statements (1) (2) (3) (4) (5) are correct or not.
First of all let's understand what's going on with the documentation you quoted.
The following commands show git blame
output of Activity.java
file in AOSP:
$ cd $AOSP/frameworks/base
$ git blame ./core/java/android/app/Activity.java
The relevant part of the output:
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 363) * <p>Note the "Killable" column in the above table -- for those methods that
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 364) * are marked as being killable, after that method returns the process hosting the
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 365) * activity may killed by the system <em>at any time</em> without another line
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 366) * of its code being executed. Because of this, you should use the
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 367) * {@link #onPause} method to write any persistent data (such as user edits)
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 368) * to storage. In addition, the method
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 369) * {@link #onSaveInstanceState(Bundle)} is called before placing the activity
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 370) * in such a background state, allowing you to save away any dynamic instance
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 371) * state in your activity into the given Bundle, to be later received in
550116576 (RoboErik 2014-07-09 15:05:53 -0700 372) * {@link #onCreate} if the activity needs to be re-created.
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 373) * See the <a href="#ProcessLifecycle">Process Lifecycle</a>
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 374) * section for more information on how the lifecycle of a process is tied
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 375) * to the activities it is hosting. Note that it is important to save
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 376) * persistent data in {@link #onPause} instead of {@link #onSaveInstanceState}
5c40f3fcc (Daisuke Miyakawa 2011-02-15 13:24:36 -0800 377) * because the latter is not part of the lifecycle callbacks, so will not
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 378) * be called in every situation as described in its documentation.</p>
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 379) *
0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 380) * <p class="note">Be aware that these semantics will change slightly between
0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 381) * applications targeting platforms starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB}
0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 382) * vs. those targeting prior platforms. Starting with Honeycomb, an application
0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 383) * is not in the killable state until its {@link #onStop} has returned. This
0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 384) * impacts when {@link #onSaveInstanceState(Bundle)} may be called (it may be
0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 385) * safely called after {@link #onPause()} and allows and application to safely
0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 386) * wait until {@link #onStop()} to save persistent state.</p>
0aae2d4e0 (Dianne Hackborn 2010-12-07 23:51:29 -0800 387) *
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 388) * <p>For those methods that are not marked as being killable, the activity's
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 389) * process will not be killed by the system starting from the time the method
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 390) * is called and continuing after it returns. Thus an activity is in the killable
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 391) * state, for example, between after <code>onPause()</code> to the start of
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800 392) * <code>onResume()</code>.</p>
Note that the paragraph that discusses post-Honeycomb behavior was added by Dianne Hackborn on 2010-12-07, whereas the enclosing paragraphs date back to 2009-03-03.
What it tells us is that Dianne added the new paragraph without updating the rest of the javadoc, therefore the contradiction. Unfortunately, this is not rare in Android.
To your questions:
1) On post-Honeycomb versions of Android both onResume()
and onStop()
are guaranteed to be called (as stated by Dianne Hackborn in her addition to Activity's javadoc).
2) On pre-Honeycomb only onPause()
is guaranteed to be called (as stated by the earlier version of Activity's javadoc)
3,4,5) onDestroy()
will not be called only if the process hosting the entire application is killed. When the process is killed, all resources allocated to it are freed, therefore there is no risk of memory leak in this case.
Important note: since releasing resources in onDestroy()
will not cause memory leak, it might look like a good idea to put all the "releasing" code there. However, it is rarely the optimal approach. Why? Read below.
When Activity
goes to background it is stopped, but not destroyed (usually). Activity
can remain in this "stopped" state for quite a long time, and will be started again if the user returns to the application. If you release resources in onDestroy()
, which is not called by default when Activity
goes to background, the Activity
will hold to these resources while in stopped state, thus causing higher amount of resources to be consumed by your app in background state.
When Android runs out of memory, it starts killing the processes in order to free the memory consumed by them. One of the most important considerations taken into account when choosing which processes to kill is their resource consumption. Thus, if your app holds to resources while in background stopped state, it will have higher chance of being killed by Android.
In addition, we, the developers, must make sure that we make the best apps for our users. Application that consumes non-minimal amount of user phone's resources and battery while in background is not a good application. And the users will know about it!
Therefore, I strongly advice releasing all resources in onStop()
method. I don't usually overwrite onDestroy()
methods in Activities
and Fragments
at all.
Corollary: As pointed out by @Juan in his comment, the above important note has an equally important, but not so evident corollary: onStart()
should be the only method in which resources are being allocated. Whatever your definition of "resources" is, neither onCreate()
nor onResume()
should allocate these resources.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With