As of Android 3.0 (SDK Level 11), there is a great facility for saving and restoring the state of your fragments for your Android application.

What Is It

I’m midcycle in the development of my next Android application and while browsing the Android API reference, stumbled upon FragmentManager.putFragment(Bundle, String, Fragment) and FragmentManager.getFragment(Bundle, String).  What do they do?

putFragment

Put a reference to a fragment in a Bundle. This Bundle can be persisted as saved state, and when later restoring [getFragment(Bundle, String)](http://developer.android.com/reference/android/app/FragmentManager.html#getFragment(android.os.Bundle, java.lang.String)) will return the current instance of the same fragment.

getFragment

Retrieve the current Fragment instance for a reference previously placed with [putFragment(Bundle, String, Fragment)](http://developer.android.com/reference/android/app/FragmentManager.html#putFragment(android.os.Bundle, java.lang.String, android.app.Fragment)).

From my understanding, when you place an existing, attached fragment into a bundle, the OS saves a pointer to the fragment somewhere.  When you call getFragment, it will return you the instance of the fragment of which you saved the pointer to in putFragment.

You can also take advantage of the FragmentManager APIs to save a fragment “pointer” in a bundle and later retrieve it, to allow you to maintain direct pointers across state save/restore. -Diane Hackborn, Android framework engineer - Source

How To Use It

One way I leverage this API is during the destruction and creation of my application activity.  Since the advent of fragments, I tend to use two activities, one to house my application and one for settings.  I manage my fragments in my application activity.

putFragment

In my my activity’s onSaveInstanceState looks like this:

@Override
protected void onSaveInstanceState(Bundle outState) {
   FragmentManager manager = getFragmentManager();
   manager.putFragment(outState, MyFragment.TAG, mMyFragment);
}

MyFragment is a fragment I’ve implemented in my application.  The bundle, outState, is simply the bundle that will store the pointer to your fragment.  MyFragment.TAG is a String key to access this pointer later on.

getFragment

I have a custom method (instantiateFragments) that will do one of two things, instantiate my fragment from scratch if my application is cold starting or access the existing MyFragment reference.

private void instantiateFragments(Bundle inState) {
   FragmentManager manager = getFragmentManager();
   FragmentTransaction transaction = manager.beginTransaction();

   if (inState != null) {
      mMyFragment = (MyFragment) manager.getFragment(inState, MyFragment.TAG);
   } else {
      mMyFragment = new MyFragment();
      transaction.add(R.id.fragment, mMyFragment, MyFragment.TAG);
      transaction.commit();
   }
}

I call instantiateFragments from my application activity, passing in null as the parameter (since onCreate signifies cold application start to me) and from onRestoreInstanceState, which called when the application is hot started, passing in the bundle received here.

@Override
protected void onRestoreInstanceState(Bundle inState) {
   instantiateFragments(inState);
}

In the scenario where a user rotates their device, Android will destroy your application’s activity(s).  Before destroying them it calls, onSaveInstanceState, allowing developers to persist data.  Once the activity is recreated post rotation, the OS will call onRestoreInstanceState giving developers a chance to restore the application state pre-rotation. I encourage you to continue with even deeper investigation into the Android framework because there are all types of nuances that will make ease the effort with Android application development.

🧇