This chapter discusses the relationship of the lifecycle of fragments to that of activities, and demonstrates the appropriate programming actions at the various points in the lifecycle. The special purpose fragment classes ListFragment and DialogFragment are introduced with coverage of their use and how their behavior in the activity lifecycle differs from that of standard fragments.
The following topics are covered in this chapter:
ListFragment classDialogFragment classDialogFragment class as a traditional Dialog classDialog class in a DialogFragment classBy the end of this chapter, we will be able to coordinate the setup and teardown of fragments within their host activities, and be able to effectively utilize the ListFragment and DialogFragment classes.
One of the challenges of developing Android applications is assuring that our applications effectively handle the lifecycle of the application's activities. During the lifetime of an application, a given activity may be created, destroyed, and recreated many times. A simple action such as a user rotating a device from a portrait to landscape orientation, or vice-versa, normally causes the visible activity to be completely destroyed and recreated using the appropriate resources for the new orientation. Applications that do not cooperate effectively with this natural lifecycle will often crash or behave in some other undesirable manner.
As we know, each fragment instance exists within a single activity; therefore, that fragment must cooperate in some way with the activity lifecycle. In fact, not only do fragments cooperate with the activity lifecycle but also they are intimately connected.
In both the setup and display phase and hide and teardown phase, fragments provide many of the same lifecycle-related callback methods as activities. In addition, fragments provide additional lifecycle-related callback methods that relate to the fragment's relationship to the containing activity.
As our applications become more sophisticated and we work with more specialized implementations of the fragment class, understanding the fragment class' lifecycle and the relationship to the activity lifecycle is essential.
If you are unfamiliar with the basics of Android's activity lifecycle callback methods, please see the Activity Lifecycle section of the Android Activity documentation at http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle.
Fragment setup and display is a multiphase process involving the fragment's association with an activity, the fragments' creation, and the standard lifecycle events of moving the activity into the running state (also known as the resumed or active state). Understanding the behavior of the lifecycle events and the associated callback methods is essential for using fragments effectively. Once we have an understanding of the lifecycle events and the callback methods, we'll look at just how the event callback methods are used.
The following diagram shows the sequence of lifecycle-related callback method calls that occur on fragments and activities during setup and display:

As you might expect, in most cases, the first step in the setup and display of a fragment occurs in the activity's onCreate method. In most cases, the activity calls the setContentView method from within the activity's onCreate callback method, which then loads the layout resource and triggers the activity's association with the contained fragments.
Notice what happens next. Before the fragment is ever created, the fragment is attached to the activity. The fragment is first notified of the attachment and receives a reference to the activity through the onAttach callback method. The activity is then notified and receives a reference to the fragment through the onAttachFragment callback method.
Although attaching the fragment to the activity prior to creating the fragment may seem unexpected, doing so is useful. In many cases, the fragment needs access to the activity during the creation process, because the activity often contains information that the fragment will display or that is otherwise important to the fragment creation process.
With the fragment attached to the activity, the fragment then performs general creation work in the onCreate method and then constructs the contained view hierarchy in the onCreateView method.
When an activity contains multiple fragments, Android calls the four methods: Fragment.onAttach, Activity.onAttachFragment, Fragment.onCreate, and Fragment.onCreateView in succession for one fragment before making any calls to these methods for the next fragment. This allows each fragment to complete the process of attachment and creation before the next fragment begins that process.
Once the sequence of calling these four methods completes for all the fragments, the remaining setup and display callback methods are called individually in succession for each fragment.
After the activity completes execution of its onCreate method, Android then calls each fragment's onActivityCreated method. The onActivityCreated method indicates that all views and fragments created by the activity's layout resource are now fully constructed and can be safely accessed.
At this point, the fragment receives the standard lifecycle callbacks on the onStart and onResume methods, just after the activity methods of the same name are each called. Any work performed in the fragment's onStart and onResume methods is very much like the work performed in the corresponding methods within an activity.
For many fragments, the only methods in this part of their lifecycle that are overridden are the onCreate and onCreateView methods, as we saw in the examples in the previous chapters.
The activity and fragment classes have a number of commonly named callback methods, and most of these commonly named methods have a common purpose. One important exception is the onCreateView method. The purpose of this method is very different for each class.
As mentioned previously, Android calls the Fragment class' onCreateView method to give the fragment an opportunity to create and return the fragment's contained view hierarchy. This method is commonly overridden within a fragment.
The method of the same name in the Activity class is called repeatedly by the LayoutInflater class during the process of inflating a layout resource. Most activity implementations do not override this method.
Just as fragments behave in a similar way to activities during setup and display, they also behave in a similar way during hide and teardown, as shown in the following diagram:

Initially during hide and teardown, fragments behave just as activities. When the user switches to another activity, each fragment's onPause, onSaveInstanceState, and onStop methods are called. For each method, the fragment implementation is called first, followed by the activity implementation.
After the onStop method is called, fragments begin to behave a little differently than activities. Consistent with the separation of fragment creation from fragment view hierarchy creation, fragment view hierarchy destruction is separate from fragment destruction. Following the call to the activity's onStop method, the fragment's onDestroyView method is called indicating that the view hierarchy returned by the fragment's onCreateView method is being destroyed. The fragment's onDestroy method is then called followed by the fragment's onDetach method. At this point, the fragment has no association with an activity and any calls to the
getActivity method will return null.
For activities containing multiple fragments, Android calls the sequence of the three methods, onDestroyView, onDestroy, and onDetach, for an individual fragment, before beginning the sequence of calling these three methods for the next fragment. This groups the process of destroying and detaching each fragment similar to the way Android groups the process of attaching and creating each fragment. Once this sequence completes for all fragments, Android then calls the activity's onDestroy method.
For the most part, lifecycle management for a fragment is very much like that of an activity. There is, however, one important exception: the two-phase nature of fragment creation and destruction. Fragments separate the creation and destruction of the fragment from the fragment's contained view hierarchy. This is because fragments have the ability to exist and be associated with an activity in the absence of the fragment's view hierarchy.
There are many scenarios where an activity may contain multiple fragments, but have only a subset of those fragments visible at any point in time. In such a case, the contained fragments can all have their onAttach
and onCreate methods called. But the call to each fragment's onCreateView method is delayed until the time comes for the app to make the contents of that fragment visible. Similarly, when the time comes to hide the contents of a fragment, only the fragment's onDestroyView method is called, not the onDestroy and onDetach
methods.
This behavior comes into play when fragments are dynamically managed within an activity. This behavior allows the overhead of associating a fragment with an activity and initializing the fragment's state to occur only once while being able to easily change the visibility of the fragment's view hierarchy. This is important when we explicitly manage the visibility of fragments using the FragmentTransaction class, and in certain action bar features that manage fragments. We'll talk about these issues in the next two chapters.
For many fragment implementations, the most important callback method in the lifecycle sequence is the onSaveInstanceState method. Just as with an activity, this callback method provides the fragment with an opportunity to persist any state before the fragment is destroyed, such as when the user moves to another activity or when the user rotates the device to a different orientation. In both of these cases, the activity and contained fragments may be completely torn down and recreated. By persisting the fragment state in the onSaveInstanceState method, that state is latter passed back to the fragment in both the onCreate
and onCreateView methods.
When managing the state of a fragment, you want to be sure to separate work that is general to the fragment's overall existence from work specific to setting up the view hierarchy. Any expensive initialization work that's general to the fragment's existence such as connecting to a data source, complex calculations, or resource allocations should occur in the onCreate method rather than the onCreateView method. This way, if only the fragment's view hierarchy is destroyed and the fragment remains intact, you avoid unnecessarily repeating expensive initialization work.