Fragments restoration magic (mechanism)

In my last post, where I described a problem of incorrect usage of Fragments instantiation inside FragmentPageAdapter & ViewPager, I wrote:

After orientation change all fragments currently added to FragmentManager are automatically restored and instantiated so there is no need to create them once again.

Today, I want to focus more specifically on an issue how this automatic restoration works under the hood.

Beginning

The simplest way to use a fragment:

A custom fragment instance is created and added to FragmentManager with help of FragmentTransaction.
We could add that our Fragment will be added to container identified by android.R.id.content.

This is the easiest case. I want to point out that we are not using setRetainInstance(true) inside our custom fragment implementation, and our activity is not protected in manifest agains any type of configuration changes.

The Question

Now, what will happen with our fragment if suddenly our device configuration will change, i.e. orientation?

Android Source Code (especially FragmentActivity and FragmentManager/FragmentManagerImpl) is a place where we should look for the answer.

1. Saving the state

Before Activity will be destroyed itsonSaveInstanceState method will be called. Take a look what this method is doing internally.

It takes mFragments (reference to FragmentManager held in this Activity) and callsFragmentManager.saveAllState() method which will return a parcelable object ready to be saved inside the bundle which, you can already guess… later will be used to restore Fragments.

In reality result of saveAllState method call is an object of typeFragmentManagerState which consists of information about all active fragments and back stack entries

Last quick look at FragmentState.

It consists of all data which describes a specific fragment object instance, like container id, tag, arguments but also savedFragmentState.

It looks sufficient to create fragments from scratch, and set them like they were before.

2. Destroying fragments and activities.

After state of fragments is saved via FragmentManager activity object is destroyed (removed from memory) with all its fragments (those which are not retained with setRetainInstance(true)).

3. Creating activity and recreating fragments

Final point is a recreation of the activity and recreation of the fragments. It starts within the first Activity lifecycle callback method onCreate(Bundle savedInstanceState)

The previously saved fragment manager state bundle now is used inside FragmentManager.restoreAllState method. This metod declaration is quite long but I want to focus on the most important part.

Array with all FragmentState objects is iterated. And every FragmentState object is used to recreate (create new instance with state like before) specific Fragments.

A new instance of a fragment is created by platform with usage of reflection and default constructor – that’s why you must remember to always ensure the existence of public non-argument fragment constructor and initialize your fragment through arguments bundle (not with usage of fragment object setters from strange places).

This is short story how restoration of Fragments works.

Conclusion

Points to remember:

  • Already created fragments are restored automatically after orientation change
  • Magic behind this is just code written in Activity together with FragmentManager logic/implementation
  • Avoid setter methods and parametrized constructors to modify fragment state, because platform uses only default (0 parameter) constructor, arguments bundle and saved state bundle to restore it later
  • Fragments are not so bad
 

Michał Łuszczuk

Lead Android developer @Blix-Qpony Group