Android Adventures - Lifecycle And State
Written by Mike James   
Monday, 10 June 2013
Article Index
Android Adventures - Lifecycle And State
The Bundle
Advanced State Management

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

states1

 

If you think about it for a moment this isn't unreasonable  as the app is being loaded, becoming visible and assuming the foreground. 

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. However this isn't the complete story. The system does retain the state of UI elements that can be modified by the user and it automatically restores them when the app starts. 

This 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.

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.

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 an 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.

 

edittextin

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

Saving Additional UI Data

There are lots of ways of saving the the state of an app as it is started and stopped by the system. One of the simplest is to ue the Bundle object that the system uses. 

The system fires the onSaveInstanceState event when it is about to add data to the Bundle and save it. If you want to save some additional data all you have to do is override the default event handler. 

For example, suppose you want to save and restore the data in the TextView in the Lifecycle explorer. First you have to save the data:

@Override
protected void onSaveInstanceState(

                   Bundle savedInstanceState){
savedInstanceState.putCharSequence(
              "myText",textView.getText());
 super.onSaveInstanceState(savedInstanceState);
}

Notice that we save the text content of the textView object as the value and use the key "myText". In most cases it would be better to create a string constant for the key. 

Now to retrieve the data and place it into the TextView we need to change the onCreate event handler:

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

This starts off in the usual way but now we check to see if savedInstanceState has any data. If it does we retrieve the stored text using the key "myText". 

You can also override the onRestoreInstanceState function in the same way if you want to keep the onCreate event handler looking simple.

There are set and get methods for a range of standard data types and often all you need to do to make sure that your app maintains its state between system restarts is to use the savedInstanceState Bundle object. Notice you can save arbitrary data and not just data for the layout.

As an exercise you can now go back to iCalc introduced in the previous chapter and make its display and current value persist through a screen rotate.



Last Updated ( Thursday, 20 November 2014 )
 
 

   
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.