Understanding the Android Application Lifecycle with a Hands-on Example

March 19, 2012

The Android documentation is really pretty good. And you can whine about how things are put together — the nature of the APIs, or the Frameworks implementation, but really, it could be a lot worse. And for platforms come and gone, I think it was a lot worse, way-back-when. That’s part of why you’re bothering to read this right now, right!

Anyway, here’s a blog about the Android Application Lifecycle, viewed from the eye of some simple get-started-already code.

Setup Our Test Code

mkdir LifecycleTest
cd LifecycleTest

android create project \
    --target "Google Inc.:Google APIs:10" \
    --path . \
    --package org.nosemaj.lifecycle_test \
    --activity LifecycleTest \
    --name LifecycleTest

Okay, fine. Now let’s create a simple Activity which will show us whenever a new lifecycle change occurs:

In src/org/nosemaj/lifecycle_test/LifecycleTest.java, I have:

package org.nosemaj.lifecycle_test;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class LifecycleTest extends Activity {
    public static final String TAG = LifecycleTest.class.getName();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate()");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG, "onStart()");
    }
     
    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i(TAG, "onRestart()");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "onPause()");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, "onStop()");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy()");
    }
}

Boom. Wham, bam; presto.

Moving right along, then, let’s build the thing and start seeing what gets called when:

ant clean; # out of habit
ant debug
adb install bin/LifecycleTest-debug.apk

Some Common Activity Change Scenarios

Let’s consider a few scenarios we might want to test, which occur frequently to an Application in the wild:

  1. The app is started from the launcher.
  2. The user hits the “Back” button while in the app.
  3. The user hits the “Home” key while in the app.
  4. The user does nothing, and the screen goes to sleep.
  5. The user wakes up the phone to resume the app.
  6. The user launches a new application, whilst the one we’re testing is running.
  7. The screen orientation changes

There might be some other important things, but that seems like a good start to get our feet wet.

So let’s start observing messages:

adb logcat | grep LifecycleTest

The app is started

I/ActivityManager(   61): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.nosemaj.lifecycle_test/.LifecycleTest } from pid 126
I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onRestart()
I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onStart()
I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onResume()

Look like the documentation.

The user hits the “Back” button:

I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onPause()
I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onStop()
I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onDestroy()

The Back key destroys the app.

The user hits the “Home” key:

I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onPause()
I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onStop()

Aha, no onDestroy(), this time.

The screen falls asleep

I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onPause()

Just only onPause() gets called this time.

The screen wakes up to the app

I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onResume()

Something gets launched over this app

I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onPause()
I/org.nosemaj.lifecycle_test.LifecycleTest(  371): onStop()

Screen orientation changes

I/org.nosemaj.lifecycle_test.LifecycleTest(23872): onPause()
I/org.nosemaj.lifecycle_test.LifecycleTest(23872): onStop()
I/org.nosemaj.lifecycle_test.LifecycleTest(23872): onDestroy()
I/org.nosemaj.lifecycle_test.LifecycleTest(23872): onCreate()
I/org.nosemaj.lifecycle_test.LifecycleTest(23872): onStart()
I/org.nosemaj.lifecycle_test.LifecycleTest(23872): onResume()

Wow, a slew of stuff. The application gets destroyed — only to be recreated again in new skin a moment later. Baller.

Conclusion

Well, so that’s probably enough of that for now wouldn’t you say?

Anyway, I think the point is that onPause() and onResume() are the only really reliable ones. You might save a little gas by putting a select few lines in onCreate(), but probably better to put the volatile stuff in onResume().

If you want to play around with this code, I’ve posted it to Github.

One Response to “Understanding the Android Application Lifecycle with a Hands-on Example”

  1. Ryan says:

    Thank you for this. I’m going through http://darkdigitalera.com/sites/default/files/files/ebooks/Sams%20Teach%20Yourself%20Android%20Application%20Development%20in%2024%20Hours%20(7Summits).pdf and your work helped me understanding this better. Now I can see the activity in the log, as opposed to staring at a blank page. :) Thanks

Leave a Reply