2.4重建活动
在以下几个场景中,由于正常的应用程序的行为,你的活动会被销毁:当用户按下“ 返回“按钮,或您的活动调用finish()方法表示自身的销毁。当活动目前已停止而且在很长一段时间没有使用,系统也会销毁你的活动。或者如果前台活动需要更多的资源,系统必须关闭后台进程回收内存。
当用户按下返回或活动结束自己,系统对该活动实例的概念就会永远消失,因为这些行为表明不再需要该活动了。然而,如果由于系统的限制(而不是正常的应用程序的行为)让系统销毁了活动,即使实际的 活动实例已经不存在了,系统仍会记得它曾经存在,当用户导航回来的时候,系统会使用一组之前保存的数据创建一个新的实例,这些数据描述了活动被销毁时的状态。系统用来还原到之前状态所保存的数据,被称为“实例状态”,它是存储在Bundle对象中的一个键-值对集合。
注意:用户每次旋转屏幕时你的活动都会被销毁并重新创建。当屏幕改变方向,系统会销毁并重建前景活动,是因为屏幕的配置已经改变,你的活动可能需要加载替换资源(如布局)。
默认情况下,系统采用Bundle实例状态保存活动布局中每个视图对象的信息(EditText对象中输入的文本值)。所以,如果你的活动实例被销毁并重新创建,不需要你写任何代码,布局的状态就可以恢复到之前的状态。然而,你的活动可能有更多你想要恢复的状态信息,如跟踪用户在活动中进度的成员变量。
注:为了让Android系统还原活动中视图的状态,每个视图必须有一个唯一的ID, 由android
:id
属性提供。
为了保存额外的活动状态的数据,你必须重写onSaveInstanceState()回调方法。系统在用户离开你的活动时调用这个方法,并把Bundle对象传递给它,Bundle对象在您的活动意外销毁的事件中保存。如果系统稍后必须重建活动实例,它传递相同的对象到onRestoreInstanceState()和onCreate() 方法。
图2。系统开始停止你的活动时,它会调用onSaveInstanceState()方法(1),所以你可以指定你想保存的状态数据,以防必须重新活动实例。如果活动被销毁而必须重新创建相同的实例,系统传递在(1)中定义的状态数据到onCreate()方法(2)和onRestoreInstanceState()方法(3)。
保存您的活动状态
活动开始停止时,系统调用onSaveInstanceState(),这样可以以键-值对集合的方式保存您的活动状态信息。这种方法的默认实现保存活动的视图所有层次结构的状态信息,如EditText部件的文本或某个ListView的滚动位置。
为了保存您的活动额外的状态信息,你必须实现onSaveInstanceState()方法并把键-值对添加到Bundle对象。例如:
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save theuser's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Always callthe superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
注意:始终调用超类的实现onSaveInstanceState(),这样默认实现可以保存视图的层次状态。
还原活动状态
当你的活动在销毁后被重建时,你可以从系统传递给你的活动的Bundle还原保存的状态。onCreat()和onRestoreInstanceState()回调方法获得相同包含实例的状态信息的Bundle。
因为系统创建你的活动一个新的实例或重建之前那个都会调用onCreate()方法,在你尝试读取状态Bundle时你必须先检查它是否为空。如果它是空的,那么系统是在创建活动的一个新实例,而不是还原之前被销毁的一个实例。
例如,下面是你在onCreate() 中还原一些状态数据的方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Checkwhether 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()方法,系统会在OnStart()方法后调用它。系统只在有保存的状态可以还原时才会调用onRestoreInstanceState()方法,所以你不需要检查包Bundle是否为空:
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always callthe superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restorestate members from saved instance
mCurrentScore =savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel =savedInstanceState.getInt(STATE_LEVEL);
}
注意:始终调用超类的实现onRestoreInstanceState(),这样默认实现可以还原视图的层次状态。。
要了解更多关于由于运行时重新启动事件而导致重建您的活动的信息(例如当屏幕旋转时),请参阅处理运行时更改。