details of Android application components destruction and recreation-ThrowExceptions

Exception or error:

Could someone push me in the direction of some concrete, trustworthy (and preferably concise) information on the following:

  1. The order in which components are destroyed and (where applicable)recreated by the system
    (Fragment, Activity, Activity’s Threads/AsyncTasks/Timers,
    static data(when are classes unloaded?), Threads/AsyncTasks/Timers in other classes, host
    TabActivity, ActivityGroup, bound local Services, Application, process)
    both when the app is in the background, and in the foreground.
    At which points the destruction can stop (what states can be encountered
    upon return to the app – like “everything including the Application object
    destroyed, process alive”?

  2. Is it possible (without modifying Android) to programmatically cause the same kind of destruction
    ourselves, so that it is indistinguishable from when the system does it, or is a separate mechanism needed for when we ourselves choose to free memory (triggered by onLowMemory)?

  3. Reliable reproduction steps of all scenarios from 1) (would junit.framework do? I haven’t investigated that) ?

  4. If the user leaves a task for a long time, the system clears the task of all activities except the root activity. When the user returns to the task again, only the root activity is restored“: is this aside from the process/component lifecycle/destruction, or tied to it?

I have read various sources give pieces of information, often incomplete and misleading, sometimes incorrect.
I admit, I have skimmed over some parts of the documentation, so i may have missed or misunderstood something.

[EDIT] To avoid misunderstandings: What I am asking about is Android destroying components to free memory, bypassing Activity.onDestroy.
When I put the app in the background and return later, the one of these sequences will occur:

  • onPause, onStop, onRestart, onStart, onResume
  • onPause, onStop, Application.onCreate, onCreate(notNull), onStart, onResume

[EDIT2]
Bounty started. Need reliable info on: Activities, Fragments, Application, bound (potentially remote)Services, process.
Partial/full destruction scenarios. See 1st point.

How to solve:

Credit for this goes to hackbod for writing it here(read the whole answer), and to CommonsWare for linking in a comment.

In short: All the docs, rewritten many times, continue to lie to us. They’re not misleading, they just give us untrue information. Unless you’re using Fragments (dunno if support v4 counts, too), Android frees memory by killing the whole process, or does nothing.

Of course, this does not address everything:

  • Point 4 of the question
  • Why I frequently saw onCreate(notNull) on pressing Back on an Activity stack with Activities handling all config changes (Android 2.3.7)
  • How this relates to the widely accepted belief that onPause is the last call you are certain to get, and onStop may never get called (how, then, can the app go to the background, to be killed?)

We’re getting somewhere, though.

###

This is what my experience, and that of devs I’ve asked, seems to suggest:

    • Fragments are not autodestroyed.
    • non-visible Activities on the app’s stack can be autodestroyed in any order, and in any number.
    • destroyed Activity’s (or any other class’s) Threads and statics remain untouched until Application is destroyed.
    • TimerTasks: haven’t tested.
    • bound local Services: destroyed somewhere between the destruction of the last binding Activity and of Application.
    • Application is the last thing to go within a process, and “goes” along with all Threads.
    • the process can exist for a long (20+ minutes) time after the destruction of the Application object, unless you have an automatic task killer.
    • Activities under TabActivity or in ActivityGroups are not autodestroyed, but go all at once if the container is destroyed.
      Example: a TabActivity with ActivityGroups under tabs. All Activities live. Another Activity is started, fullscreen. The TabActivity with everything in it is now eligible for destruction by Android, all at once or not at all.
  1. NO.
    If you destroy an Activity manually, it goes through the entire lifecycle and doesn’t pass a Bundle to onCreate when started again.
    Also, onLowmemory is unreliable – even with small allocation steps, it might never be called before OutOfMemoryError is thrown.
  2. NO.
    Despite the autodestruction/restoration being such a major feature in Android, there isn’t any way to test such scenarios.
  3. This is probably related only to whether the process still exists or not. If it does, Android will attempt to restore the old Activities. If not, it’s a clean restart.

The above include some assumptions.
I am still waiting for someone to confirm it and supply some docs (guarantees not dependent on the current implementation of classes).
Please, PLEASE correct me if any of this is wrong.

Edit: The above information may be out of date, it was tested on Android 2.1-2.3

###

Well, my friend,
I guess you’ll have a lot of trouble in your research. Basically because you’re talking about two black boxes: the Dalvik garbage collector and the android heap manager. I would say that you cannot trust that android will follow any order of object destruction. But, you can trust that this lifecycle is going to be followed [Programming Android, 2011]:

Activity Lifecycle:

onCreate() - Called after the instance of the activity has been created for the first  time
onRestart() - Called after an activity has been interrupted, just before the onStart();
onStart() - Called when the object activity and their visions become visible to the user;
onResume()-  Called when the object activity and their visions become interactive to the user;
onPause() - Called when a different instance of the activity is going to get visible and the present activity ceases to interact with the user
onStop() - Called when the activity is no longer visible or is not interacting
onDestroy() - Called when an activity instance must be destroyed and it's no longer needed. 

Fragments have different lifecycles including methods onAttach, onCreateView and onActivityCreated .
But, why do you care about the objects order of destruction? I can’t see no reason for you to monitor such events, but if you really need, learn more about the garbage collector.

###

  1. The ActivityManagerService#trimApplications()method remove any unused application processes if the application’s current receiver is null, does not have any activity and service.

###

When it comes to activities, they will be only destroyed on on Destroy() until and unless developer manually calls the finish() function,

Fragment life cycle is a completely matched to its parent activity, so when parent activity destroys on on Destroy(), the fragments on Destroy() as well will be called.

Timer Tasks will finish their work and become candidates for garbage collection, once the activity creates them the task runs in its own thread, no relation with activity, even if the activity is destroyed, the task finishes itself….

###

This is not a complete answer but what I would recommend is that you place toast messages in each of these methods. Add in your own onPause(), onStop(), onResume(), etc. and inside put a line like this:

Toast.makeText(this, "onPause()", Toast.LENGTH_SHORT).show();

You cannot directly call these methods, however moving another activity to the top of the stack will of cause these methods on the existing activity to be called. One more thing to keep in mind is that onCreate() need not be called every time you start an activity. It really depends on how you start the activity, for example if you send this intent

Intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);

it will appear call onNewIntent() instead if it has already been created. In summary the best thing is just to watch the Toast messages. Also you really need to focus on using the debugger. Place a breakpoint on each method and you can see it. One thing I am sure of is that you cannot directly invoke these methods like onPause(). Also keep in mind that in general you don’t know when onDestroy() will be called.

Leave a Reply

Your email address will not be published. Required fields are marked *