Activity被销毁的两中情况
Activity被销毁的情况大致可分为两种。
一是正常行为。如当用户按了手机的back键或者activity调用自己的finish()方法而被销毁。
另一种是非正常行为。如activity处于stop状态而且长期没有被使用,或者是前台的activitiy需要更多的资源因此系统必须关闭后台进程以回收内存。
Activity状态能保存的情况
当activity由于用户按下back键或activity调用finish()方法结束本身而被销毁,则该activity实例将永远消失因为它的行为表明该activity不再需要了。
如果activity被销毁是因为系统强制关闭而不是程序正常的退出行为,那么即使是acitivy的实例销毁了,但是系统仍然记得它的存在。当用户返回到该activity的时候,系统会使用它被销毁时候保存的数据来创建出一个新的activity实例。这些被系统用来恢复之前状态的数据被称为“instance state”,是一个存在Bundle对象中的键值对集合。
注意:
用户每次旋转屏幕,都会引起activity的销毁和重建。
当改变屏幕的方向时,由于屏幕的配置信息发生改变,系统会销毁和重新创建前台activity。用户可以在清单文件中配置activity的configchange属性。
信息保存在哪
默认情况下,系统会使用Bundle对象去保存activity布局中的每个view对象的信息(如刚输入在activity中的文本值)。所以当activity被销毁和重建,布局的状态会自动恢复到之前的状态。但是如果你的activity需要恢复更多的信息,比如成员变量信息,则需要自己动手写了。
存储activity的状态
在activity的生命周期中有一个额外的回调方法onSaveInstanceState(),当用户离开activity的时候,系统就会调用该方法。当系统调用这个方法时,会传递一个Bunddle对象存储额外的信息由于该activity是意外销毁。
如果activity被销毁后需重建这个activity实例时,它会传递同一个Bundle object到onRestoreInstanceState() 和 onCreate() 方法中去。如下图:
当系统停止activity时,它会调用onSaveInstanceState()(过程1),如果activity被销毁了,但是需要创建同样的实例,系统会把过程1中的状态数据传给onCreate()和onRestoreInstanceState()(图中标出的2和3)。
存储Activity状
当系统停止activity时,系统会调用onSaveInstanceState(),状态信息会以键值对的形式存储下来。该方法默认的实现中存储了activity的view的状态,比如edittext中的文本和listview滚动条的位置等。如果要存储额外的信息,必须自己实现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);
}
恢复activity的状态
当activity重建时,需要根据Bundle中的状态信息数据恢复activity。onCreate() 和onRestoreInstanceState()回调函数都会接收到这个Bundle。
因为每次创建新的activity实例的或重建一个实例的时候都会调用onCreate()方法,所以必须先检查是否Bundle是null,如果是null,则表明是要创建一个全新的对象,而不是重建一个上次被销毁的对象。
比如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()方法实现,这个方法是在onStart()之后调用。
系统只会在有数据要恢复的时候才会调用onRestoreInstanceState(),所以不必检查Bundle是否为null。
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);
}