Now I'm trying to write a (more complex) Hello World application for Android following a bunch of internet resources. I've read that an Activity has a life cycle (create/start/stop/resume/pause/destroy). This makes sense, because most UI elements (also in other frameworks) can be viewed as having lifecycles.

I found out that the activity gets destroyed and re-created every time the screen is rotated. At a first glance, it might seem a bit surprising (particularly for people coming from desktop or web UI), because the tendence is to recycle widgets & stuff. However, by destroying/recreating the Activity, devs are forced to think about the two layouts (at least) and model them according to preferences. One side-effect of this fact though is the default state persistence, or rather lack of; one must ensure that whatever is displayed is kept consistent when the Activity is recreated.

The solution listed below is the basic, handmade one.

Persisting State

My first impulse was to get all the on...() methods and use local variables (or bundles) to manage state. THIS IS WRONG! It's wrong because there's a helper method named onSaveInstanceState(Bundle) which gets called at the right times. This method does "what it says on the tin": saves the instance. For example, if you'd want an int persisted, you'd implement something like:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

    // Call the super. You never know :)
    super.onSaveInstanceState(savedInstanceState);

    // debug
    Log.i(TAG, "onSaveInstanceState");

    savedInstanceState.putInt(KEY_INT_VALUE, mMyIntValue);
}

In the code above, the mMyIntValue is e.g. a private variable.

To read the value when a new Activity is created, you can implement something like:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Check for null. Apparently, this is a
    // "best practice in android development (TM)"
    //
    if (savedInstanceState != null) {
        mMyIntValue = savedInstanceState.getInt(KEY_INT_VALUE, 0);
    }

    // ... Other relevant code
}

The code above will read whatever is saved in the bundle (with a devault value of 0 if the bundle exists but the key KEY_INT_VALUE can't be found). To make the code 100% correct, you can either place an else {} statement to initialise the value, or you can initalise mMyIntValue at declaration time (or in all constructors if you insist).

Conclusion

This is the first thing I've tried and worked. If you know better tricks, let me know and I'll add them as alternative solutions.

One alternative I've found is to use global variables instead.

Please note the problem could become a bit more intricate with 3rd party libraries or threading. then you'll need to be careful of what gets saved where.

HTH,