Android Adventures - Staying Alive!
Written by Mike James   
Thursday, 06 August 2015
Article Index
Android Adventures - Staying Alive!
The Lifecycle Explorer
Saving Additional UI Data

Lifecycle Explorer

There is no better way to feel comfortable with the lifecycle and its events than to write a short demo program that shows you when they occur. 

Start a new Android blank activity application, accepting all defaults, and call it Lifecycle and then accept all the defaults to get started quickly. 

In the layout editor remove the "Hello World" string and place a TextView on the design surface. Next resize it so that it fills most of the area - it can be tricky to get it to snap to the size and remove its default text entry.

 

lifecyclescreen2

 

The code is fairly easy the only trick is to remember to call each of the system provided event handler's that you have overridden. If you don't do this the app simply terminates when you run it. 

The OnCreate event handler still has to construct the UI but now we get a reference to the Java object representing the TextView into a global variable so that the event handlers can access it:

private TextView textView;

@Override
protected void onCreate(Bundle
                          savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 textView = (TextView)  
 findViewById(R.id.textView);
 textView.append("Create\n");
}

The rest of the program simply overrides each of the event handlers in turn, calls the original event handler and then adds a text message to textView:

@Override
protected void onStart() {
 super.onStart();
 textView.append("Start\n");
}

@Override
protected void onPause() {
 super.onPause();
 textView.append("Pause\n");
}

@Override
protected void onResume() {
 super.onResume();
 textView.append("Resume\n");
}

@Override
protected void onStop() {
 super.onStop();
 textView.append("Stop\n");
}

@Override
protected void onRestart() {
 super.onRestart();
 textView.append("Restart\n");
}

@Override
protected void onDestroy() {
 super.onDestroy();
 textView.append("Destroy\n");
}

 

A very simple and tedious sort of program - if you don't want to type it in or copy and paste it then you can find it in the CodeBin.

Trying It Out

If you now run this program you can use it to find out when the lifecycle events happen. 

You might be surprised to learn that when you first run the program you get

states2

 

If you think about it for a moment this isn't unreasonable  as the app is being loaded, becoming visible and assuming the foreground and hence the appropriate events are fired in turn. 

Beginners often assume that the life cycle events some how override each other. That is if an onCreate has been fired then this is the big event in the Activity's life and so the others wont happen. This is isn't the case and you need to make sure that you put actions into the event handlers that really are appropriate to the life cycle state. For example, if you put something in the onResume event handler make sure you realise that it is going to be fired when the app first starts up as well as when it just being resumed. 

If you try other things like pressing the Home key and selecting another app then you will see other event sequences - but of course only when you resume the Lifecycle app.

For example pressing the Home key, then showing the task manager by long pressing the Home key and reselecting your app results in: Pause, Stop as the app is removed from the foreground and then Restart, Start, Resume as the app is loaded, becomes visible and then resumes the foreground and interacts with the user.

You can try other actions out but there is one thing you must try out - change the orientation. If you are using the emulator then press Ctrl-F11. When the screen orientation changes you will see that the TextView has been cleared and  Create, Start, Resume have been added. 

This is because when you change orientation the app is completely stopped and then completely restarted, i.e. it is as if the app was being run from scratch for the first time. 

This statement is almost true - but not quite. 

Retaining State - The Bundle

When you change orientation your app is stopped and restarted. When this happens the TextView is reset to its default state when the app loads.

From our description of what is happening this is perhaps what you might expect. However this isn't the complete story.

The system does try to help you with the problem of having your app stopped in its tracks and restarted.

It will automatically retain the state of UI elements that can be modified by the user and it automatically restores them when the app starts. So in principle you can initially ignore the problem of an app restart because the system restores your UI. This is the reason that some Android programmers assume that everything is "normal" and there is no need to study the lifecycle of an app. This is true at first but later your app will evolve beyond what the system provides by default. 

Automatically saving and restoring the UI's state is what the savedInstanceState parameter in the onCreate event handler is all about:

 protected void onCreate(
               Bundle savedInstanceState) {

A Bundle is a set of key value pairs and when you app is stopped by the system it uses it to save the values stored in UI elements that can be modified by the user. It stores id/value pairs and when the app is restarted the Bundle is used to initialize the values in the corresponding UI elements.  

Notice that if the user stops your app by removing it say from the recent apps list then the savedInstanceState is destroyed and the app really does start over afresh and the onCreate isn't passed a Bundle to restore the UI. 

In other words savedInstanceState only restores the UI when the app has been stopped by the system. 

It is also worth noticing that the restore will work to an alternative layout loaded because of a configuration change. For example it will restore state to a landscape version of a layout as well as the original portrait version. All that matters is that the current layout has View objects with the correct ids.

At this point you are probably wondering why the TextView object wasn't restored by the system when then device was rotated? 

The simple answer is that a TextView object isn't intended for user interaction - it is supposed to just be used to show static text labels and so the system doesn't save and restore it. 

You can see the automatic save and restore in action if you add an EditText input field on the design surface of the Lifecycle explorer. Now if you enter some text into the EditText field it will be retained if you rotate the device. However if you press and hold the Home key, remove the app and then start it afresh you will see that the EditText field is blank again.

 

edittextin2

 

The text in the EditText field at the bottom of the screen is preserved during a screen rotation.

The general principle is that any UI element that can be modified by the user is automatically saved and restored. Any changes that your code makes or that the user makes in  complex UI components are lost unless you take steps to preserve them.

Androidgears



Last Updated ( Wednesday, 12 October 2016 )