The secret to successful configuration change design is not to put "stuff" inside an activity that cannot be easily re-created during a configuration change.
Keep data and business logic outside of activities if you can.
There are three callbacks to be aware of when dealing with configuration changes in activities.
onSaveInstanceState()
onCreate()
onRestoreInstanceState()
The onSaveInstanceState() callback will be called prior to the call to onStop()
onSaveInstanceState() callback could go through the currently active view hierarchy and saves the values for each view that has an android:id.
A few methods in the android.os.Bundle class:
- putInt()
- putString()
- putParcelable()
@Override
public void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
icicle.putInt("counter", 1);
}
It's up to you whether you restore state in onCreate() or in onRestoreInstanceState(). Many applications will restore state in onCreate() because that is where a lot of initialization is done. One reason to separate the two would be if you're creating an activity class that could be extended. The developers doing the extending might find it easier to just override onRestoreInstanceState() with the code to restore state, as compared to having to override all of onCreate().
Objects to avoid in bundles include Drawables, Adapters, Views, and anything else that is tied to the activity context.
Four fragment callbacks receive this Bundle object when a fragment is being re-created.
- onInflate();
- onCreate();
- onCreateView();
- onActivityCreated();
Don‘t traverse the view hierarchy inside of onSaveInstanceState() in a fragment.
Using FragmentManager to Save Fragment State
- saveFragmentInstanceState()
- Fragment.SavedState
- setInitialSavedState()
A fragment can avoid being destroyed and re-created on a configuration change if the
setRetainInstance() method is called with an argument of true.
But it only works for fragments that are not on the backstack.
Summary
- Activities get destroyed and re-created during configuration changes.
- Avoid putting lots of data and logic into activities so configuration changes occur quickly.
- Let Android provide the appropriate resources.
- Use singletons to hold data outside of activities to make it easier to destroy and re-create activities during configuration changes.
- Take advantage of the default onSaveInstanceState() callback to save UI state on views withandroid:ids.
- If a fragment can survive with no issues across an activity destroy and create cycle, use setRetainInstance() to tell Android it doesn't need to destroy and create the fragment.