解释保存状态的 Android 文档和一篇关于在活动和片段中保存状态的非常好的文章。
保存和恢复 Activity 状态 在某些情况下,您的 Activity 会由于正常的应用行为而被破坏,例如当用户按下“后退”按钮或您的 Activity 通过调用发出自己的破坏信号时finish() 方法。如果 Activity 处于 Stopped 状态且长时间未使用,或者前台 Activity 需要更多资源,系统也可能会销毁包含您的 Activity 的进程以恢复内存。
当您的 Activity 因用户按下“返回”或 Activity 自行结束而被销毁时,系统对 Activity 实例的概念将永远消失,因为该行为表明不再需要该 Activity。但是,如果系统由于系统限制(而不是正常的应用程序行为)而破坏了活动,那么虽然实际的 Activity 实例已经消失,但系统会记住它的存在,因此如果用户导航回它,系统会创建使用一组保存的数据来描述活动被销毁时的状态的活动的新实例。系统用来恢复之前状态的保存数据称为实例状态,是存储在Bundle对象中的键值对的集合。
默认情况下,系统使用Bundle 实例状态来保存有关活动布局中每个View 对象的信息(例如输入到EditText 小部件中的文本值)。 因此,如果您的 Activity 实例被销毁并重新创建,则布局的状态将恢复到之前的状态,而无需您编写任何代码。但是,您的 Activity 可能有更多您想要恢复的状态信息,例如跟踪用户在 Activity 中的进度的成员变量。
保存您的活动状态
当您的活动开始停止时,系统会调用onSaveInstanceState() 方法,以便您的活动可以使用键值对集合保存状态信息。此方法的默认实现保存有关 Activity 视图层次结构状态的临时信息,例如 EditText 小部件中的文本或 ListView 小部件的滚动位置。
注意:您必须始终调用onSaveInstanceState() 的超类实现,以便默认实现可以保存视图层次结构的状态。
要为您的 Activity 保存其他状态信息,您必须覆盖 onSaveInstanceState() 并将键值对添加到在您的 Activity 意外销毁时保存的 Bundle 对象。例如:
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);
}
注意:为了让 Android 系统恢复 Activity 中视图的状态,每个视图都必须有一个唯一的 ID,由 android:id 属性提供。
要保存持久性数据,例如用户偏好或数据库数据,您应该在活动处于前台时抓住适当的机会。如果没有这样的机会出现,您应该在onStop() 方法期间保存这些数据。
恢复您的活动状态
当您的 Activity 在之前被销毁后重新创建时,您可以从系统传递给您的 Activity 的 Bundle 中恢复您保存的状态。 onCreate() 和 onRestoreInstanceState() 回调方法都接收包含实例状态信息的同一个 Bundle。
因为onCreate()方法被调用,无论系统是创建一个新的Activity实例还是重新创建前一个实例,你必须在尝试读取它之前检查状态Bundle是否为空。如果为 null,则系统正在创建 Activity 的新实例,而不是恢复之前被破坏的实例。
例如,下面的代码sn-p显示了如何恢复onCreate()中的一些状态数据:
@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
}
...
}
您可以选择实现onRestoreInstanceState(),而不是在onCreate() 期间恢复状态,系统在onStart() 方法之后调用它。系统调用onRestoreInstanceState()只有在有保存状态需要恢复,所以不需要检查Bundle是否为空:
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);
}
注意:始终调用onRestoreInstanceState() 的超类实现,以便默认实现可以恢复视图层次结构的状态。