Sunday, May 5, 2013

How setRetainInstance(true) affect lifecycle of Fragment

It's part of the articles of lifecycle: start reading from Understand lifecycle of Activity and Fragment, Introduction.

The Fragment.setRetainInstance() method control whether a fragment instance is retained across Activity re-creation (such as from a configuration change). This can only be used with fragments not in the back stack. If set, the fragment lifecycle will be slightly different when an activity is recreated:
  • onDestroy() will not be called (but onDetach() still will be, because the fragment is being detached from its current activity).
  • onCreate(Bundle) will not be called since the fragment is not being re-created.
  • onAttach(Activity) and onActivityCreated(Bundle) will still be called.
~ reference: http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)

Refer to the last exercise, "UI elements lost after Activity/Fragment re-created". Consider the image_c, it is loaded in onCreateView(), only if savedInstanceState == null. Without setRetainInstance(true), it will not be loaded after orientation changed, because savedInstanceState != null.

image_c lost after orientation changed, without setRetainInstance(true)


MYTAG LogCat listed here:

Orientation changed:
  • MainActivity.onPause
  • MyFragment1.onPause
  • MainActivity.onStop
  • MyFragment1.onStop
  • MainActivity.onDestroy
  • MyFragment1.onDestroyView
  • MyFragment1.onDestroy
  • MyFragment1.onDetach
  • MainActivity.onCreate / savedInstanceState != null
  • MyFragment1.onAttach
  • MyFragment1.onCreate / savedInstanceState != null
  • MainActivity.onStart
  • MyFragment1.onCreateView / savedInstanceState != null
  • MyFragment1.onActivityCreated / savedInstanceState != null
  • MyFragment1.onStart
  • MainActivity.onResume
  • MyFragment1.onResume


To know how setRetainInstance(true) affect lifecycle of Fragment, modify MyFragment.java from last exercise "UI elements lost after Activity/Fragment re-created", override onActivityCreated() method to call setRetainInstance(true).

 @Override
 public void onActivityCreated(Bundle savedInstanceState) {
  recLifeCycle_with_savedInstanceState(savedInstanceState);
  super.onActivityCreated(savedInstanceState);
  
  setRetainInstance(true);
 }

image_c reloaded after orientation changed, with setRetainInstance(true).

LogCat in Orientation Changed:
  • MainActivity.onPause
  • MyFragment1.onPause
  • MainActivity.onStop
  • MyFragment1.onStop
  • MainActivity.onDestroy
  • MyFragment1.onDestroyView
  • MyFragment1.onDetach
  • MainActivity.onCreate / savedInstanceState != null
  • MyFragment1.onAttach
  • MainActivity.onStart
  • MyFragment1.onCreateView / savedInstanceState == null
  • MyFragment1.onActivityCreated / savedInstanceState == null
  • MyFragment1.onStart
  • MainActivity.onResume
  • MyFragment1.onResume



download filesDownload the files.

* the original chart of fragment lifecycle is taken here.

5 comments:

Anonymous said...

thanks

Anonymous said...

very well presented.

Wave Writer said...

I found it useful and informative, thanks for the effort building the Figures.

Anonymous said...

"This can only be used with fragments not in the back stack."
Could you give us an example to support your statement? As I know we can use setRetainInstance() with fragments in the back stack.

Joca said...

Very nice post. Simple and straight to the point. You know what? A picture is worth a thousand words. Thanks!