Android App Development : Activity Life Cycle

Activity Life Cycle

Official Documentation

Activity class provides a core set of six callbacks: onCreate(), onStart(), onResume(), onPause(), onStop(), and onDestroy(). The system invokes each of these callbacks as an activity enters a new state.

Android Activiy Lifecycle

Orientation Changes


Nice Tutorial on Handling Orientation Changes

Fragment Life Cycle

Normal Behaviour

If you rotate your device when you have an Activity that is NOT using the configChanges flag and a Fragment that IS being retained, the following lifecycle methods will be called on the Fragment:

onPause
onSaveInstanceState
onStop
onDestroyView
onDetach
onAttach
onCreateView
onActivityCreated
onStart
onResume

Android does not call onCreate and onDestroy because we retained the Fragment; nor does it call the constructor, because the same Fragment instance will be used after the orientation change. Android will call all of the other callbacks because the Fragment’s parent Activity IS being destroyed and recreated, so the Fragment does have to go through the process of being detached then reattached.

Option 1 android:configChanges

Setting the android:configChanges flag on your Activity in AndroidManifest.xml as shown below:

<activity
    android:name=".MyActivity"
    android:label="@string/title_my_activity"
    android:configChanges="orientation|screenSize|keyboardHidden" />

Cons:

Instead of destroying and recreating your Activity, Android will just rotate the screen and call one of the lifecycle methods: onConfigurationChanged. You would have to implement onConfigurationChanged and manually discard the old layout/View, inflate the new layout and display it — which is a lot more work and can make your code difficult to work with in the future.

Fragment.setRetainInstance(true)

Calling setRetainInstance(true) on a Fragment is similar to setting the android:configChanges flag on an Activity. It signals to Android that you want to continue using the same instance of the current Fragment, so all of your member variables will remain untouched.

Option 2 : android:screenOrientation

<activity
    android:name=".MyActivity"
    android:label="@string/title_my_activity"
    android:screenOrientation="portrait" />

This altogether prevents orientation changes from happening while the user is in the Activity with the flag set. So if you rotate your device the screen won’t rotate with it.

Option 3 : Saving State

This involves implementing the onSaveInstanceState method (this could be in your Activity, Fragment or both) and placing the values you need to save in the Bundle argument that gets passed to the method.

This means that if you use any custom Views, they should contain an implementation of onSaveInstanceState. Do note, that in order for a View’s state to be saved it MUST have an android:id attribute because this is essentially used as the key for that particular View’s state.

private static final String STATE_COUNTER = "counter";
private int mCounter;
...
@Override
protected void onSaveInstanceState(Bundle outState) {
    // Make sure to call the super method so that the states of our views are saved
    super.onSaveInstanceState(outState);
    // Save our own state now
    outState.putInt(STATE_COUNTER, mCounter);
}

The same Bundle object is used in onCreate of the Activity

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         ...    
    // If we have a saved state then we can restore it now
    if (savedInstanceState != null) {
        mCounter = savedInstanceState.getInt(STATE_COUNTER, 0);
    }    
    // Display the value of the counter
    mCounterTextView = (TextView) findViewById(R.id.counter_text);
    mCounterTextView.setText(Integer.toString(mCounter));

ListViews poses extra requirements for restoring state. Watch the tutorial for details.

Using onRestoreInstanceState

if you want to wait for all of your onCreate initialization to be done before restoring state or if you want to allow subclasses to specifically handle restoring state. An Activity’s onRestoreInstanceState is called after onStart and before onResume.