ReCreating an Activity
- 某些情况下你的Activity会因为正常的用户行为被销毁,比如用户触发返回键,activity会调用finish()函数来销毁自己。系统也可能会因为前台程序需要资源而把后台程序杀死来腾出内存空间。
- 当你的Activity是因为用户按返回键而调用finish()来销毁的,一般意味着用户不再需这个Activity。系统对这中Activity已经没有概念。但是因为系统的限制(如内存不够,而不是用户正常行为)而被销毁,虽然实际的Activity的实例已经被销毁,但是系统会以key-value对的形式将该Activity销毁前的数据保存在Bundlle对象中,当用户返回来时,系统用这些数据重新创建一个新的Activity实例
- 注意:当用户旋转屏幕时,你的Activity会被销毁并重建。因为当屏幕方向改变时,屏幕配置已经改变,系统可能需要重新加载相应资源
- 默认情况下,系统会使用bundle对象来保存你的Activity布局中每个view 对象(比如你在EditText中输入的文字)。所以如果你的Activity实例被销毁然后被重新创建,你不用写任何代码,Activity就会回到之前的状态。但是可能有些状态 数据你也想恢复,比如那些用来标记和追踪用户行为的成员变量。
note:为了使android 系统能够在Activity中恢复view的状态。每个view必须有一个ID 可以用android:id属性来标记
保存你的Activity状态
当你的Activity开始stop的时候,系统调用onSaveInstanceState()函数,你的Activity因此可以保存状态信息。默认onSaveInstanceState()函数会保存Activity view层面的状态数据,比如EditText中的文本或者ListView滚动的位置.为了可以保存额外的状态信息,你必须实现onSaveInstanceState()函数,并且以key—value对的形式将信息保存在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来恢复你保存的状态。onCreate() 和onRestoreInstanceState()接收相同的存储状态信息的bundle。因为不管是系统创建一个Activity的实例或者是重新创建一个之前的Activity都会调用onCreate()。但你试图去读取bundle的时候你必须去检查bundle 是否为空。如果为空则系统是在创建一个新的实例,如果不为空,则是恢复一个实例。比如:
@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()
中去恢复Activity的状态,这个函数在onStart()之后调用。系统只会在恢复一个已经存储的Activity状态时才会调用这个函数。这样,你就不用去判断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() 。这样能默认地去恢复试图层的状态。