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

有几个你的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";
...

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

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

恢复Activity的状态


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

由于onCreate() 方法在系统创建一个新的activity实例和重建activity实例时都会被调用,在你尝试使用状态Bundle时,你必须要检查它是否为空,这样系统就会创建一个新的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()方法,系统会在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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值