在某些场景下,Activity会因为一般的应用软件行为而销毁,如用户点击了Back按钮,或是Activity通过调用Finish()将自己销毁。Android系统也会将长时间未被使用处于Stopped状态的Activity销毁,当运行在前台的Activity需要更多的资源,系统为了释放内存也会将后台进程关闭。
当用户点击了Back按钮,或是Activity通过调用Finish()将自己销毁,对于系统来说,这个Activity不再被需要。然而,如果Activity是因为系统限制(而不是一般的应用软件行为)被系统销毁,系统仍然会记录这个Activity实例的存在,当用户返回到这个Activity,系统会根据Activity销毁时保留的一些记录信息重新创建一个实例。系统用来恢复之前的状态的记录数据被称为“实例状态”,是一个存储在Bundle对象中的键值对的集合。
警告:每次用户旋转屏幕都会导致Activity的销毁和重建。当屏幕方向发生变化,系统就会销毁然后重建前台Activity,因为屏幕配置发生了变化,Activity也可能需要使用相应的替代资源(如界面布局)。
默认情况下,系统使用Bundle实例状态来存储Activity界面布局中每个View对象的信息(如EditText对象中输入的文本内容)。因此,当Activity被销毁后又重建,界面布局的状态会自动被系统恢复到之前的状态。然而,开发者通常都希望保存更多需要恢复的状态信息,例如用于跟踪用户在Activity中的进程的成员变量。
注意:为了让Android系统能够恢复Activity中各个View的状态,每个View都必须通过android:id属性来指定一个唯一的ID值。
为了保存Activity状态的一些额外数据,开发者必须覆写onSaveInstanceState()回调方法。系统在用户离开一个Activity时以Bundle对象为参数调用该方法,Bundle对象会在Activity被意外销毁时保存。当系统需要重建Activity时,将这个Bundle对象传递给onRestoreInstanceState()方法和onCreate()方法。
Activity状态保存
当Activity开始进入Stop状态时,系统调用onSaveIntanceState()方法,使得Activity通过一些键值对的集合将状态信息保存。这个方法默认保存Activity的View架构的状态信息,如EditText部件的文本或者一个ListView的滚动信息。
为了保存Activity的额外信息,开发者需要执行onSaveInstanceState(),向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);
}
警告:总是调用super类的onSaveInstanceState()执行默认操作以确保将View架构的状态信息得到保存。
Activity状态恢复
当Activity被销毁后又重建,开发者可以通过系统传递给Activity的Bundle对象将之前保存的状态恢复。onCreate()方法和onRestoreInstanceDat()方法都会收到这个包含实例状态信息的Bundle对象。
由于onCreate()方法会在系统新建一个Activity实例或者重建一个之前存在过的实例两种时机调用,开发者必须在读取Bundle对象之前检查其是否为null。如果Bundle对象为null,则可以确定此时系统是在新建一个Activity实例。
例如,下面的代码展示在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
}
...
}
除了在onCreate()方法中恢复状态,开发者也可以在之后调用的onRestoreInstanceState()方法中实现状态恢复。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);
}
警告:总是调用super类的onRestoreInstanceState()执行默认操作以确保将View架构的状态信息得到恢复。