Buy @ Amazon

Search This Blog

August 27, 2017

Android Activity's onDestroy() Ain't Your Reliable Friend



Look at the Android Activity life-cycle events in the picture beside.

The lifecycle isn't something new. You're familiar with it right? You're also that good Android developer that writes clean code, wherein you consciously override onDestroy() method to include resources clean-up code and save some state, right?

Per Android doc, it is okay and usually the practice to write cleanup code in this method but not anything beyond that.

So if you are to write code to persist state in this method, or anything else beyond resource clean-up (like threads associated with an activity), you're better off to push it up the life-cycle, either in onStop() or onPause() method.

That is how I settled in the first iteration of new learning but wasn't happy. Why? To quote Android Doc:

There are situations where the system will simply kill the activity's hosting process without calling this onDestroy() 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.
What are those other methods that aren't guaranteed to be called? So is my learnings in the first iteration right? I'm really thirsty to know the right way of doing things - "what fits where?".

And then this SO thread and Android Doc - Activity, quenched my thirst to come up with the following points in learning:
1. In pre-Honeycomb versions of Android onPause(), onStop() and onDestroy() are all potential-killer methods in that when these methods gets executed and returns, the process hosting the activity may be killed by the system at any time without another line of its code being executed. Thus there is no guarantee that onStop() and onDestroy() will be called.
2. In post-Honeycomb versions of Android onStop() and onDestroy() are both potential-killer methods. Thus there is no guarantee that onDestroy() will be called.
3. 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.

Based on these new lessons that we just learned, we arrive at the following practices:
1. Use the onPause() or onSaveInstanceState(Bundle) method to write any persistent data (such as user edits) to storage.
2. Given that there is no risk of memory leak even if onDestroy() method is not called, it might seem okay to write resource clean-up code here. But don't. Prefer to write clean-up code in the onStop() method.
3. As you put this learning into practice, ensure the sanity of creation/destruction goes in onStart()/onStop() or onResume()/onPause() pairs. Don't mix and match, lest your app's users might see weird app behaviours.


Additional Reading

When an 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() method, which is not called when that Activity goes to background, the Activity will continue to hold to its resources in that stopped state, thus causing higher amount of OS 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 and the app state. Thus, if your app holds to resources while in background (stopped state), it likely calls for the attention of Android OS to kill it.

Great developers strive to make the best apps for end-users. App that consumes unwarranted amount of user phone's resources while in background is not a good application. Weather or not the users know about it, Google Play gets to know it, affecting the app's ranking in the play store.

Therefore, let's write clean-up code in onStop() method. Let's avoid overwriting onDestroy() methods in Activities, Fragments, et. all.


References

1. Android doc - Activity Lifecycle - onDestroy() section
2. SO - Release resources in onPause instead of onDestroy
3. Android onStop/onDestroy - when might these be used?
4. Android doc - Activity Lifecycle - See killable column of the table