| page.title=Recreating an Activity |
| parent.title=Managing the Activity Lifecycle |
| parent.link=index.html |
| |
| trainingnavtop=true |
| previous.title=Stopping and Restarting an Activity |
| previous.link=stopping.html |
| |
| @jd:body |
| |
| <div id="tb-wrapper"> |
| <div id="tb"> |
| |
| <h2>This lesson teaches you to</h2> |
| <ol> |
| <li><a href="#SaveState">Save Your Activity State</a></li> |
| <li><a href="#RestoreState">Restore Your Activity State</a></li> |
| </ol> |
| |
| <h2>You should also read</h2> |
| <ul> |
| <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">Supporting |
| Different Screens</a></li> |
| <li><a |
| href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a></li> |
| <li><a href="{@docRoot}guide/components/activities.html">Activities</a> |
| </li> |
| </ul> |
| |
| </div> |
| </div> |
| |
| <p>There are a few scenarios in which your activity is destroyed due to normal app behavior, such as |
| when the user presses the <em>Back</em> button or your activity signals its own destruction by |
| calling {@link android.app.Activity#finish()}. The system may also destroy your activity if it's |
| currently stopped and hasn't been used in a long time or the foreground activity requires more |
| resources so the system must shut down background processes to recover memory.</p> |
| |
| <p>When your activity is destroyed because the user presses <em>Back</em> or the activity finishes |
| itself, the system's concept of that {@link android.app.Activity} instance is gone forever because |
| the behavior indicates the activity is no longer needed. However, if the system destroys |
| the activity due to system constraints (rather than normal app behavior), then although the actual |
| {@link android.app.Activity} instance is gone, the system remembers that it existed such that if |
| the user navigates back to it, the system creates a new instance of the activity using a set of |
| saved data that describes the state of the activity when it was destroyed. The saved data that the |
| system uses to restore the previous state is called the "instance state" and is a collection of |
| key-value pairs stored in a {@link android.os.Bundle} object.</p> |
| |
| <p class="caution"><strong>Caution:</strong> Your activity will be destroyed and recreated each time |
| the user rotates the screen. When the screen changes orientation, the system destroys and recreates |
| the foreground activity because the screen configuration has changed and your activity might need to |
| load alternative resources (such as the layout).</p> |
| |
| <p>By default, the system uses the {@link android.os.Bundle} instance state to save information |
| about each {@link android.view.View} object in your activity layout (such as the text value entered |
| into an {@link android.widget.EditText} object). So, if your activity instance is destroyed and |
| recreated, the state of the layout is restored to its previous state with no |
| code required by you. However, your |
| activity might have more state information that you'd like to restore, such as member variables that |
| track the user's progress in the activity.</p> |
| |
| <p class="note"><strong>Note:</strong> In order for the Android system to restore the state of |
| the views in your activity, <strong>each view must have a unique ID</strong>, supplied by the |
| <a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code |
| android:id}</a> attribute.</p> |
| |
| <p>To save additional data about the activity state, you must override |
| the {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} callback method. |
| The system calls this method when the user is leaving your activity |
| and passes it the {@link android.os.Bundle} object that will be saved in the |
| event that your activity is destroyed unexpectedly. If |
| the system must recreate the activity instance later, it passes the same {@link |
| android.os.Bundle} object to both the {@link android.app.Activity#onRestoreInstanceState |
| onRestoreInstanceState()} and {@link android.app.Activity#onCreate onCreate()} |
| methods.</p> |
| |
| <img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" /> |
| <p class="img-caption"><strong>Figure 2.</strong> As the system begins to stop your activity, it |
| calls {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} (1) so you can specify |
| additional state data you'd like to save in case the {@link android.app.Activity} instance must be |
| recreated. |
| If the activity is destroyed and the same instance must be recreated, the system passes the state |
| data defined at (1) to both the {@link android.app.Activity#onCreate onCreate()} method |
| (2) and the {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} method |
| (3).</p> |
| |
| |
| |
| <h2 id="SaveState">Save Your Activity State</h2> |
| |
| <p>As your activity begins to stop, the system calls {@link android.app.Activity#onSaveInstanceState |
| onSaveInstanceState()} so your activity can save state information with a collection of key-value |
| pairs. The default implementation of this method saves information about the state of the activity's |
| view hierarchy, such as the text in an {@link android.widget.EditText} widget or the scroll position |
| of a {@link android.widget.ListView}.</p> |
| |
| <p>To save additional state information for your activity, you must |
| implement {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} and add |
| key-value pairs to the {@link android.os.Bundle} object. For example:</p> |
| |
| <pre> |
| static final String STATE_SCORE = "playerScore"; |
| static final String STATE_LEVEL = "playerLevel"; |
| ... |
| |
| @Override |
| public void onSaveInstanceState(Bundle savedInstanceState) { |
| // Save the user's current game state |
| savedInstanceState.putInt(STATE_SCORE, mCurrentScore); |
| savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel); |
| |
| // Always call the superclass so it can save the view hierarchy state |
| super.onSaveInstanceState(savedInstanceState); |
| } |
| </pre> |
| |
| <p class="caution"><strong>Caution:</strong> Always call the superclass implementation of {@link |
| android.app.Activity#onSaveInstanceState onSaveInstanceState()} so the default implementation |
| can save the state of the view hierarchy.</p> |
| |
| |
| |
| <h2 id="RestoreState">Restore Your Activity State</h2> |
| |
| <p>When your activity is recreated after it was previously destroyed, you can recover your saved |
| state from the {@link android.os.Bundle} that the system |
| passes your activity. Both the {@link android.app.Activity#onCreate onCreate()} and {@link |
| android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} callback methods receive |
| the same {@link android.os.Bundle} that contains the instance state information.</p> |
| |
| <p>Because the {@link android.app.Activity#onCreate onCreate()} method is called whether the |
| system is creating a new instance of your activity or recreating a previous one, you must check |
| whether the state {@link android.os.Bundle} is null before you attempt to read it. If it is null, |
| then the system is creating a new instance of the activity, instead of restoring a previous one |
| that was destroyed.</p> |
| |
| <p>For example, here's how you can restore some state data in {@link android.app.Activity#onCreate |
| onCreate()}:</p> |
| |
| <pre> |
| @Override |
| protected void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); // Always call the superclass first |
| |
| // Check whether we're recreating a previously destroyed instance |
| if (savedInstanceState != null) { |
| // Restore value of members from saved state |
| mCurrentScore = savedInstanceState.getInt(STATE_SCORE); |
| mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); |
| } else { |
| // Probably initialize members with default values for a new instance |
| } |
| ... |
| } |
| </pre> |
| |
| <p>Instead of restoring the state during {@link android.app.Activity#onCreate onCreate()} you |
| may choose to implement {@link |
| android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}, which the system calls |
| after the {@link android.app.Activity#onStart()} method. The system calls {@link |
| android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} only if there is a saved |
| state to restore, so you do not need to check whether the {@link android.os.Bundle} is null:</p> |
| |
| <pre> |
| public void onRestoreInstanceState(Bundle savedInstanceState) { |
| // Always call the superclass so it can restore the view hierarchy |
| super.onRestoreInstanceState(savedInstanceState); |
| |
| // Restore state members from saved instance |
| mCurrentScore = savedInstanceState.getInt(STATE_SCORE); |
| mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); |
| } |
| </pre> |
| |
| <p class="caution"><strong>Caution:</strong> Always call the superclass implementation of {@link |
| android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} so the default implementation |
| can restore the state of the view hierarchy.</p> |
| |
| <p>To learn more about recreating your activity due to a |
| restart event at runtime (such as when the screen rotates), read <a |
| href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a>.</p> |
| |