Android学习路线(十五)Activity生命周期——重新创建(Recreating)一个Activity

来源:互联网 发布:linux定时任务crontab 编辑:程序博客网 时间:2024/05/29 14:16

有几个你的activity由于正常行为被销毁的场景,例如当用户点击了返回键,或者你的activity接收到自身调用 finish()方法发送的销毁信号。系统还可能会销毁那些被停止后长时间没有被使用到的activity,或者前台的activity需要更多的资源,系统会关闭后台进程来回收内存。

当你的activity由于用户点击返回键或者自己关闭而被销毁,这个Activity 实例在系统的概念上已经永远消失,因为这个行为表示这个activity不再被需要。然而,如果是由于系统限制(而不是普通的应用行为)导致系统销毁activity实例,那么即使Activity 实例已经消失,系统会记得它曾经存在过,所以当用户再次回到它时,系统会使用当时销毁activity时保存的数据集来为它重新创建一个实例。这个被系统使用来载入activity之前状态的数据集被称为"instance state" ,它是一个键值对的集合,被存储在一个Bundle 对象中。

注意: 每次用户切换横竖屏时你的activity都会被销毁然后重新创建。当屏幕方向改变时,系统销毁并重建前台activity是由于屏幕配置已经变化,你的activity可能需要加载另一个资源(例如布局)。

在默认情况下,系统使用Bundle instance state 来存放每个View对象的信息。因此,如果你的应用被销毁并重建,布局会被重新加载到之前的状态,不需要其他代码。然而,你的activity可能有更多的状态希望被重新载入,例如记录用户在activity中进程的成员变量。

提示: 为了让Android系统恢复你的activity中的view的状态,每个view都必须拥有一个唯一的ID,通过android:id 属性被指定。

为了保存关于activity状态的附加的数据,你必须覆盖onSaveInstanceState() 方法。当用户离开你的activity时系统会调用这个方法,通过它,当你的activity被异常销毁时Bundle 对象会被保存起来。如果系统之后必须重新创建activity实例,它会将相同的Bundle 对象同时传给onRestoreInstanceState() 和onCreate() 方法。

图 2. 当系统开始停止你的activity时,它会调用onSaveInstanceState() (1)方法,因此你可以指定你想要的数据保存起来。如果这个activity被销毁,那么当同样的实例被创建的时候,系统会将同样的状态数据同时传给onCreate() 方法 (2) 和onRestoreInstanceState() 方法(3)。

保存Activity状态


当你的activity开始停止时,系统调用onSaveInstanceState() ,这样你的activity可以使用键值对来保存状态信息。这个方法的默认实现会保存activity的view的层次结构,例如EditText中的文本或者ListView的滑动位置。

要为你的activity保存额外的状态信息,你必须实现onSaveInstanceState() 方法,并且把信息添加到Bundle 对象中。例如:

static final String STATE_SCORE = "playerScore";static final String STATE_LEVEL = "playerLevel";...@Overridepublic 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);}

注意: 一定要调用onSaveInstanceState() 方法的父类的实现,这样默认的实现会保存view层次结构的状态。

恢复Activity的状态


当你的activity在销毁后被重建,你可以通过系统传递给你的Bundle 对象来恢复你所保存的状态。onCreate() 和onRestoreInstanceState() 会同时受到相同的包含状态信息的Bundle 对象。

由于onCreate() 方法在系统创建一个新的activity实例和重建activity实例时都会被调用,在你尝试使用状态Bundle时,你必须要检查它是否为空,这样系统就会创建一个新的activity实例,而不是重建之前被销毁的那个。

例如,下面是如何在onCreate()方法中恢复状态:

@Overrideprotected 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 是否为空:

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);}

注意: 一定要调用onSaveInstanceState() 方法的父类的实现,这样默认的实现会保存view层次结构的状态。

学习更多关于在运行时重建你的activity(例如屏幕旋转)的信息,请参阅Handling Runtime Changes。

27 0