Explore Java and more with Jeff 'JavaJeff' Friesen

Android Activity Lifecycle

Android applications make extensive use of activities, which are focused actions with which users can interact, and which are implemented by subclasses of the android.app.Activity class. This article explores an Activity subclass's lifecycle.

Because you'll probably want to compile and run the article's code, and because you might not have the Android SDK installed, I recommend that you first read my Hello, Android! article.

Lifecycle Overview

The Android OS maintains a stack of activities. A new activity that's started is placed on top and becomes the running (current) activity. The previous running activity remains below the running activity, and won't return to the foreground until the current activity exits.

An activity exists in one of four major states:

  • active or running: The activity is at the top of the stack -- it's running.
  • paused: The activity has lost focus but is still visible -- a new non-full-sized or transparent activity has focus on top. The activity is still alive (it maintains all of its state and member information, and remains attached to the window manager), but can be killed by the OS in extreme low memory conditions.
  • stopped: The activity is completely obscured by the activity on top. It retains all state and member information, but is no longer visible to the user so its window is hidden. Furthermore, the activity will often be killed by the OS when memory is needed elsewhere.
  • dead: The paused or stopped activity has had its application process killed by the OS. The activity must be fully restarted and restored to its previous state before it can be displayed once more to the user.

As an activity moves from state to state, Activity callback methods are invoked to notify the subclass of what's happening. Activity provides the following callback methods (which should always call their superclass counterparts when overridden):

  • protected void onCreate(Bundle savedInstanceState): This method is called when this activity is initially created. It provides a place to create views, bind data to lists, and perform other operations whose results must exist until onDestroy() is called. Also, this method is called with an android.os.Bundle instance that contains this activity's previously saved state, if this state was saved. Otherwise, null is passed. Finally, onCreate() is always followed by onStart().
  • protected void onRestart(): This method is called after this activity has been stopped and prior to it being restarted. Also, onRestart() is always followed by onStart().
  • protected void onStart(): This method is called when this activity is becoming visible to the user. Also, onStart() is followed by onResume() if this activity is coming to the foreground, or onStop() if this activity is becoming hidden.
  • protected void onResume(): This method is called when this activity can start to interact with the user -- this activity is now at the top of the activity stack and receives focus. Also, onResume() is always followed by onPause().
  • protected void onPause(): This method is called when the OS is about to resume a previous activity. The onPause() method is typically used to commit unsaved changes to persistent storage, and stop animations and other time-consuming processor activities. This method should run quickly because the next activity cannot be resumed until onPause() returns. Finally, onPause() is followed by onResume() if this activity is returning to the foreground, or onStop() if this activity is becoming hidden. After this method returns, the process hosting this activity may be killed by the OS at any time without another line of code being executed.
  • protected void onStop(): This method is called when this activity is no longer visible to the user -- another activity has resumed and is covering this activity. This situation can happen when a new activity is being started, an existing activity is being brought to the foreground, or this activity is being destroyed. The onStop() method is followed by onRestart() if this activity is returning to the foreground, or onDestroy() if this activity is being terminated. After this method returns, the process hosting this activity may be killed by the OS at any time without another line of code being executed.
  • protected void onDestroy(): This method is called when this activity is being terminated. After this method returns, the process hosting this activity is killed by the OS.

The activity's entire lifetime ranges from onCreate(Bundle) (where resources are acquired) through onDestroy() (where resources are released). For example, the activity might create a thread to download network data in onCreate() and stop the thread in onDestroy().

The activity's visible lifetime ranges from onStart() though onStop(). The user can see the activity on the screen (if it isn't completely covered by the foreground activity), but cannot interact with the activity because it isn't running. This method pair can be called multiple times.

The activity's foreground (user-interactive) lifetime ranges from onResume() through onPause(). An activity can frequently transition between resumed and paused states -- when a device goes to sleep and is awakened, for example -- so these methods should run quickly.

Lifecycle Demonstration

I've created a simple Java application (see Listing 1) that demonstrates activity lifecycle. This application's Lifecycle class subclasses Activity, overrides the aforementioned methods, and has each method send a message to the standard output device when invoked.

// Lifecycle.java

package ca.mb.javajeff.lifecycle;

import android.app.Activity;

import android.os.Bundle;

public class Lifecycle extends Activity
{
   @Override
   public void onCreate (Bundle savedInstanceState)
   {
      super.onCreate (savedInstanceState);
      System.out.println ("onCreate() called");
   }

   @Override
   public void onRestart ()
   {
      super.onRestart ();
      System.out.println ("onRestart() called");
   }

   @Override
   public void onStart ()
   {
      super.onStart ();
      System.out.println ("onStart() called");
   }

   @Override
   public void onResume ()
   {
      super.onResume ();
      System.out.println ("onResume() called");
   }

   @Override
   public void onPause ()
   {
      super.onPause ();
      System.out.println ("onPause() called");
   }

   @Override
   public void onStop ()
   {
      super.onStop ();
      System.out.println ("onStop() called");
   }

   @Override
   public void onDestroy ()
   {
      super.onDestroy ();
      System.out.println ("onDestroy() called");
   }
}

Listing 1: Lifecycle.java

Assuming that you've worked your way through my Hello, Android! article, installing the Android SDK and learning how to use various command-line tools, follow these steps to create and install (on the emulator) Lifecycle:

  1. Create a Lifecycle project: android create project -t 2 -p C:\prj\dev\Lifecycle -a Lifecycle -k ca.mb.javajeff.lifecycle
  2. Replace the skeletal contents of C:\prj\dev\Lifecycle\src\ca\mb\javajeff\lifecycle\Lifecycle.java with Listing 1.
  3. Assuming that C:\prj\dev\Lifecycle is the current directory, invoke ant debug to process this directory's build.xml file and build the Lifecycle app in debug mode.
  4. Launch the emulator using the AVD (Android Virtual Device) previously created in "Hello, Android!": emulator -avd my_avd16
  5. Install the lifecycle-debug.apk file in the emulator: adb install C:\prj\dev\Lifecycle\bin\Lifecycle-debug.apk

After adb finishes, the emulator's app screen should include a generic Android icon with Lifecycle appearing directly underneath -- see Figure 1. This indicates that the Lifecycle app has been installed.

Click the Lifecycle icon to launch this app. (Click
to enlarge.)

Figure 1: Click the Lifecycle icon to launch this app. (Click to enlarge.)

Before you launch this app, invoke adb logcat in a command window to redirect emulator messages to that window. You need to do this in order to see the messages that are output via the System.out.println() method calls. Check out Figure 2.

Messages sent since Lifecycle was launched. (Click
to enlarge.)

Figure 2: Messages sent since Lifecycle was launched. (Click to enlarge.)

Figure 2 reveals that onCreate(), onStart(), and onResume() are invoked in that order. The Lifecycle activity is now on the top of the stack and receives focus. However, if you press the home button in the keyboard area, it will lose focus and you'll see Figure 3's messages.

Messages sent when we return to the home menu.
(Click to enlarge.)

Figure 3: Messages sent when we return to the home menu. (Click to enlarge.)

Return to the emulator's app screen and click the Lifecycle icon. This time, you won't see an onCreate() called message in the command window. Instead, as Figure 4 shows, an onRestart() called message outputs.

Messages sent when we re-launch Lifecycle. (Click to
enlarge.)

Figure 4: Messages sent when we re-launch Lifecycle. (Click to enlarge.)

The one message that you probably won't see is onDestroy() called. You only see this message when you explicitly terminate the activity via Activity's public void finish() method, or when the OS terminates the activity (when not running) because it needs more space.

Conclusion

For more lifecycle information, including an activity state-transition diagram that shows callback method invocations, check out Android's documentation on the Activity class.


Download code.zip

Note: All code created and tested with Android SDK 1.6, Java SE 6u16, and Apache Ant 1.7 on the Windows XP SP3 platform.


LEARN JAVA FROM APRESS