Saturday, October 13, 2012

Android Activity Life Cycle

Android apps with UI interaction are composed of one or more Activity. It's crucial to understand Activity life cycle just as ASP.NET developers have to know how the Page object is constructed. Following image from Android developer guide shows the overall flow:

A few notes on events for different user actions:

  1. Hit home/power button: onPause() => onStop(). Stop state means in Activity in background, and it's no longer visible on the screen. From documentation Android OS could kill the activity process (onDestroy() will be called) when memory reaches a low point, but I can't effectively reproduce that in a physical device.
  2. From 1 back to activity: onRestart() => onStart() => onResume(). This is quite straightforward. If the low-memory-kill-background-process happened, a new Activity instance will be recreated from scratch.
  3. Hit back button: onPause() => onStop() => onDestroy(). The previous Activity will show up and current activity is destroyed and gone. The app will close if no previous activity exists in navigation history.
  4. Rotate the screen from landscape to portrait or vise verse: onPause() => onStop() => onDestroy() => onCreate() => onStart() => onResume(). The whole activity is destroyed and recreated. That's very different from Windows 8/Windows phone 8 implementation where that only triggers an event and the instance of the page or class remains. Android considers screen rotation, language change, storage plug/unplug, etc. as "runtime configuration change". The Activity will be reloaded by default when configuration is changed, so a new layout xml file as well as other related resources can be reconstructed properly. You can skip this behavior by overriding onConfigurationChanged method to handle the situation by your own, but such approach is not recommended from Android developer guide.

Another interesting thing is the state management, two scenarios in particular: 1. background Activity is destroyed due to low memory and then is back to active Activty; 2. foreground Activity is destroyed and rebuilt because of the screen rotation. Android provides onSaveInstanceState method for you to save your data, which is executed after the onPause(0 and before the onStop() callback handlers, then you can restore the data in onCreate() method:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        // check if saved state data exists 
        if (savedInstanceState != null) {
            int prevSelectedNumber = savedInstanceState.getInt("SELECTEDNUMBER");
            // do UI logic based on prevSelectedNumber
        }
    }
 
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
 
        // save instance state data
        savedInstanceState.putInt("SELECTEDNUMBER", 123);
    }

Note that onSaveInstanceState() method is only called when the Activity is destroyed by Android OS internally like the orientation change discussed above, but it will not be called if the Activity is killed by the user action such as turning off the device or pressing the back button to go to previous Activity. In some cases, for example the address/contact input form, it would be great to keep unsaved and uncompleted data to avoid user retyping when the user is going back and forth to different screens, then the data should be saved during onPause() callback.

On top of Activities there're a set of rules defining how an Activity instance is created and behaves in one or multiple applications, e.g. a browser Activity declared as singleTask launch mode will result in only one instance running inside one Task cross the whole Android environment. The details are well described in this Android Developer Guide.