Persisting State Information During Configuration Change
One important concept you need to know when handling screen orientation changes is that when a screen changes orientation, the activity is destroyed and then recreated–the
onCreate event is always called when the screen orientation changes. When this happens, the current state of the activity may be lost.
First and foremost, you should name all your views in your activity using the android:id attribute. This attribute is important for applications that change with screen orientation, because when Android destroys activities, it saves state only for named views. For example, suppose a user changes orientation in the midst of entering some text into an EditText view. When this happens, if you've named the EditText view using an android:id attribute, Android will persist any existing text inside the EditText view, and restore it automatically when the activity is recreated. In contrast, if the view does not have an android:id attribute, the system will not be able to persist the text, so when it recreates the activity, any already-entered text will be lost.
In addition, note that the onSaveInstanceState event is fired whenever an activity is about to be killed or put into the background. For example, when the orientation is changed, this event is fired so that the current state of the activity can be saved and restored later. This event is similar to the onPause event of the Activity class, but unlike the onPause event (which is called whenever the activity is being placed in the background or being killed), it is not fired when an activity is being unloaded from the stack (since there is no need to restore its state later on).
You can override the onSaveInstanceState event and save the information you need in this event. For example, the following code shows that you can save the string ID into the Bundle object during the onSaveInstanceState event:
@Override
public void onSaveInstanceState(Bundle outState)
{
//---save whatever you need to persist—
outState.putString("ID", "1234567890");
super.onSaveInstanceState(outState);
}
When an activity is recreated, the
onCreate event is fired first, followed by the
onRestoreInstanceState event. This
onRestoreInstanceState event allows you to retrieve the state that you have saved previously in the
onSaveInstanceState event:
@Override
public void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
//---retrieve the information persisted earlier---
String ID = savedInstanceState.getString("ID");
}
While you can use the
onSaveInstanceState event to save state information, the limitation is that you can only save your state information into a
Bundle object. If you need to save more complex data structures, then this is not an adequate solution.
Another event handler that you can use is the onRetainNonConfigurationInstance event. This event is fired when an activity is about to be destroyed due to a configuration change. (Screen orientation changes are considered configuration changes, and by default, all configuration changes cause the current activity to be destroyed). You can save your current data structure by returning it in this event, like this:
@Override
public Object onRetainNonConfigurationInstance()
{
return("Hello");
}
Note that this event returns an
Object type, which pretty much allows you to return any data type. To extract the saved data, you can extract it in the
onCreate event, using the
getLastNonConfigurationInstance() method, like this:
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String str = (String) getLastNonConfigurationInstance();
}