There are numerous articles on the Internet that provide an overview of the Android Activity lifecycle, as well as the corresponding Fragment lifecycle. One thing that I have found lacking, however, is a detailed examination of the relationship between the two – in particular, exactly what events trigger what other events. Thus, I’ve set out to remedy that particular lack with this blog post. Code for this particular post may be found at https://github.com/SilverBayTech/FragmentLifeCycle.

Reviewing Android Lifecycle Events

As you’re probably aware at this point, an Activity can define the following lifecycle callbacks:

Method Description
onCreate() Called when the activity is first created. This is where you normally do your view setup, etc. This method also provides you with a Bundle containing the activity’s previously frozen state, if there was one.
onRestart() Called if your activity has been stopped and is now being restarted.
onStart() The activity is becoming visible to the user.
onResume() The activity will begin interacting with the user. It is now on the top of the activity stack, with any input from the user going to it.
onPause() The activity is no longer on the top of the activity stack. Another activity may have started on top of it, or the user may have backed out of this activity.
onStop() The activity is no longer visible to the user. Another activity may be completely obscuring this one, or it may be on its way to being destroyed.
onDestroy() The activity is being destroyed, either because of a call to finish() or because the system needs the space.

A Fragment has all of those methods, plus the following additional ones:

Method Description
onInflate() This method is not traditionally mentioned as part of the lifecycle events, as not all fragments will go through it. For fragments defined in XML, however, this offers the fragment the opportunity to obtain any XML arguments that were part of its definition.
onAttach() Called after the fragment has been associated with an activity.
onCreateView() Called when it is time for the fragment to create its own view structure.
onActivityCreated() Called once the fragment’s activity’s onCreate has been completed. As we’ll see, the activity’s onCreate is (indirectly) responsible for causing several of the fragment’s lifecycle events to be called, and the fragment’s onCreate method is called before the activity’s onCreate method has been completed.
onViewStateRestored() Tells the fragment that all of the saved state in its view hierarchy has been restored.
onDestroyView() Tells the fragment that its view is being destroyed so that it can clean up any associated resources.
onDetach() Called just before the fragment is disassociated from its activity. This is the final call before the fragment object will be released to the garbage collector.

Creating and Destroying Fragments

There are two ways that a Fragment can end up on the screen:

  1. The view defined by an activity can contain XML definitions for the fragment. This is done by embedding an XML <fragment> element within the view definition. In this case, the fragment is automatically set up when the activity’s view is inflated. I’m going to refer to this kind of fragment as being “embedded.”
  2. The activity can “manually” create the fragment and add it to the activity’s view using the FragmentManager and a FragmentTransaction. When doing this, you have the choice of having the transaction added to the FragmentManager‘s back stack or not.

Similarly, there are three ways that a Fragment can be removed from the screen:

  1. If it is part of the view for an activity and the activity’s view itself is taken off the screen, such as by the user going back to a previous activity.
  2. If, when the view was manually added to the activity, it was also added to the FragmentManager‘s back stack, and then the back stack is popped, either programmatically, or via the user pressing the back button.
  3. The app can manually remove or replace the fragment, again using the FragmentManager and a FragmentTransaction.

The code https://github.com/SilverBayTech/FragmentLifeCycle is for a simple application that allows one to explore all of these possibilities. The first activity displayed contains a “Start” button that loads a second activity. The latter is where all the “meat” is – it contains a fragment via the view’s XML, plus the ability to add an additional fragment either with or without involving the FragmentManager back stack. All the lifecycle event calls are logged so that we can see exactly what is called when.

Playing with the App

Launching an Activity with an Embedded Fragment

Pressing the “Start” button on the first activity loads the second activity, which contains the embedded fragment. If you check out LogCat, you’ll find that the sequence of events is as follows:

  1. The constructor for the new Activity is called.
  2. The activity’s onCreate() lifecycle method is called.
  3. The activity’s onCreate() method calls setContentView() passing the layout that includes the fragment definition. Before that method returns:
    1. The hosted fragment’s constructor is called
    2. The fragment’s onInflate method is called.
    3. The fragment’s onAttach method is called.
    4. The fragment’s onCreate method is called.
    5. The fragment’s onCreateView method is called.

    At this point, the activity’s call to setContentView() returns, and the rest of its onCreate method runs.

  4. The activity’s onStart method is called. As part of this method, it calls super.onStart. Before that method returns:
    1. The fragment’s onActivityCreated method is called.
    2. The fragment’s onViewStateRestored method is called.
    3. The fragment’s onStart method is called.

    At this point, the activity’s call to super.onStart returns, and the rest of the activity’s onStart method executes.

  5. The activity’s onResume method is called.
  6. The fragment’s onResume method is called. Note that unlike the previous lifecycle methods, this call is not nested within the activity’s method.

The significant takeaways here are that:

  • The calls to the super methods are critical, and
  • several of the fragment’s lifecycle methods are triggered by the activity’s call to super methods. If the relationship between the activity’s lifecycle and the fragment’s lifecycle is complex (which is obviously not ideal), this may need to be taken into account – particularly the “nesting” of the onCreate calls.

Destroying an Activity with an Embedded Fragment

The activity with the embedded fragment can be destroyed simply by pressing the “back” button to return to the initial activity. If you do this, you will see that the sequence of events is as follows:

  1. The activity’s onPause method is called. This method calls super.onPause. Before this method returns:
    1. The fragment’s onPause method is called.

    At this point the super.onPause method returns and the remainder of the activity’s method runs.

  2. The activity’s onStop method is called. This method calls super.onStop. Before this method returns:
    1. The fragment’s onStop method is called.

    At this point the super.onStop method returns and the remainder of the activity’s method runs.

  3. The activity’s onDestroy method is called. This method calls super.onDestroy. Before this method returns:
    1. The fragment’s onDestroy method is called.
    2. The fragment’s onDestroyView method is called.
    3. The fragment’s onDetach method is called.

    At this point the super.onDestroy method returns and the remainder of the activity’s method runs.

Here again, you can see the criticality of the call to the super methods, as well as the way that the calls to the fragment “nest” inside the calls to the activity.

Adding a Fragment Manually

If you press the “Add Fragment” button on the second activity, this adds manually a fragment to the bottom third of the screen. Pressing “Push Fragment” does exactly the same thing, except for the fact that the fragment is added to the FragmentManager‘s back stack.

The sequence of events in this case are:

  1. The fragment’s constructor is called.
  2. The fragment is added to the activity via a FragmentTransaction
  3. The FragmentTransaction is committed, and the method doing this work returns.
  4. Asynchronously, the fragment’s lifecycle events are called in order:
    1. onAttach
    2. onCreate
    3. onCreateView
    4. onActivityCreated
    5. onStart
    6. onResume

Here you can see that there is no “interleaving” of the fragment’s lifecycle events with that of the activity’s, since the activity is not changing state. In addition, the call to onInflate is omitted, since the fragment is not being created as part of an XML view inflation. The fact that this method isn’t always called may be one of the reasons that it’s not traditionally listed as one of the fragment lifecycle methods.

If you then press the “Remove Fragment” button, the activity manually removes the fragment from its view. Here again:

  1. The fragment is removed from the activity via a FragmentTransaction
  2. The FragmentTransaction is committed, and the method doing this work returns.
  3. Asynchronously, the fragment’s lifecycle events are called in order:
    1. onPause
    2. onStop
    3. onDestroyView
    4. onDestroy
    5. onDetach

Had you instead destroyed the activity by pressing the “back” button, you would have found that the lifecycle events for the added fragment are called in exactly the same manner as those for the hosted fragment. In my particular case, the methods for the added fragment are called after those for the hosted fragment, but it would be extremely bad design (in my opinion) to rely on this behavior.

Adding a Fragment Manually and Using the Back Stack

If, instead of “Add Fragment,” you press “Push Fragment” the fragment is added to the back stack as part of the FragmentTransaction. The only change that you will see in this case is that the BackStackListener‘s onBackStackChanged method is called. This call comes all the way at the end of the sequence – after the new fragment’s onResume call is made when the fragment is being added, and after the fragment’s onDetach call is made when the fragment is being removed. This behavior is the same whether the back stack is popped manually or via the “back” button.

Activity Reconstruction on Rotation

As you’re probably aware, unless you take steps to prevent it, when your device is rotated the operating system will typically destroy your activity and recreate it. This allows you to more easily do things like have different layouts for portrait vs. landscape.

In this case, the sequence of events is the same as the “destroy” followed by the “create” sequences above, with the following exceptions:

  1. The operating system calls the activity’s onSaveInstanceState after the activity’s onPause method returns. The activity calls its super.onSaveInstanceState as part of its own method. While this is executing:
    1. The fragments’ onSaveInstanceState methods are called.

    After the fragments have been handled, the super method returns and the activity’s onSaveInstanceState method completes.

  2. The activity’s onRestoreInstanceState method is called in between its onStart and onResume methods.

Thus, again, the call to the super method within onSaveInstanceState is important.

Fragments do not have an onRestoreInstanceState method. They are, however, passed the Bundle with the restored state information as part of their onCreate call in this case. (This argument is null if the fragment is being created, as opposed to being restored.)

Summary

As you can see, the calls to the various lifecycle methods are interleaved in a number of situations. Thus, if fragment state depends on activity state, one must be careful to understand this interleaving in order to make sure that one doesn’t try to access information before it is set.

Update – 06-Oct-2014

An eagle-eyed reader (thanks, Haluk) pointed out that I had an extra, incorrect, call to onActivityCreated listed during the fragment removal section. That was a cut-and-paste error on my part, and has been corrected.

This post was written by Kevin Hunter and originally appeared on Silver Bay Technology’s blog.