Now that we've thought about our application in the abstract, let's get back to the tangible with a little demonstration:
Launch the application, enter your first name, and press the Play button.
Observe the question asked.
Turn your phone to change the orientation (if you are in portrait mode, switch to landscape mode, and vice versa).
Repeat the operation several times.
As you can see, the question changes every time! (If it doesn't, check out the orange warning box below.)
Why? 😯
This is what we will discover in this chapter.
Change Orientation
When the Android system rotates the screen, it destroys your Activity and creates it again. Yes, I agree, that is awful.
To convince yourself of this, watch the logs as you rotate the screen:
08-07 09:41:14.669 19880-19880/com.ponroy.florian.topquiz I/System.out: GameActivity::onPause() 08-07 09:41:14.674 19880-19880/com.ponroy.florian.topquiz I/System.out: GameActivity::onStop() 08-07 09:41:14.674 19880-19880/com.ponroy.florian.topquiz I/System.out: GameActivity::onDestroy() 08-07 09:41:14.730 19880-19880/com.ponroy.florian.topquiz I/System.out: GameActivity::onCreate() 08-07 09:41:14.731 19880-19880/com.ponroy.florian.topquiz I/System.out: GameActivity::onStart() 08-07 09:41:14.732 19880-19880/com.ponroy.florian.topquiz I/System.out: GameActivity::onResume(
Yup, the Activity is stopped, then started again. Depending on the Activity, the consequence of this is more or less important:
In MainActivity, the user doesn't notice anything because their first name and their score have been loaded from the preferences at the start of the Activity, in the onCreate() method.
In GameActivity, it's more of an issue. At each start, we generate a new list of questions, and the score is lost as well.
Backup and Restore Data
Fortunately, Android does not leave us hanging. Before an Activity is stopped, Android calls the following method on it:
public void onSaveInstanceState(Bundle savedInstanceState);
Does the savedInstanceState parameter (sometimes called outState) remind you of anything? The same information is passed as a parameter to the onCreate()
method. In other words, in the onSaveInstanceState()
method, we add state data to the Bundle so we can return to that state when the Activity restarts.
The two parameters we want to save are the user's score and the index of the current question.
Saving to the Bundle is similar to saving in SharedPreferences or attaching data to an Intent: you must specify a key, and use the method corresponding to the type of the data you wish to save. Knowing that we want to save two integers, we will use the Bundle.putInt()
method.
To retrieve data more easily, create two constant keys in the GameActivity class:
public static final String BUNDLE_STATE_SCORE = "currentScore";
public static final String BUNDLE_STATE_QUESTION = "currentQuestion";
Then, save the value of the score and the index of the current question, and above all, do not forget to call the super class implementation:
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt(BUNDLE_STATE_SCORE, mScore);
outState.putInt(BUNDLE_STATE_QUESTION, mNumberOfQuestions);
super.onSaveInstanceState(outState);
}
Now, you need to recover these values in onCreate()
, making sure that the Bundle parameter has a value (it may be null, especially when the Activity starts for the first time):
if (savedInstanceState != null) {
mScore = savedInstanceState.getInt(BUNDLE_STATE_SCORE);
mNumberOfQuestions = savedInstanceState.getInt(BUNDLE_STATE_QUESTION);
} else {
mScore = 0;
mNumberOfQuestions = 4;
}
It's also possible to perform this work in onRestoreInstanceState().
You can discover how to implement that on this page.
Let's Recap!
When the Android system rotates the screen, it destroys your Activity and creates it again.
In the
onSaveInstanceState()
method, you can add all the relevant information to the Bundle so you can return to the previous state.Saving to the Bundle is identical to saving in SharedPreferences or in Intent—you specify a key and use the method corresponding to the type of data you want to save.