Activity的生命周期(四)

重新创建一个activity

翻译自官方文档API21

  在少数几种情况下,你的activity会因为APP的普通行为而被销毁,比如用户按了返回按钮或者activity自己在析构函数中调用了finish()方法。当你的activity目前处于停止状态并且长时间都没有被使用,或者是前台activity需要更多的系统资源而需要关闭后台的进程来释放内存时,系统也会销毁你的activity。

  当你的activity是因为用户按了返回按钮而终结自己时,系统就会觉得这个activity实例永远都不会存在了因为这个动作就意味着这个activity已经不是必须的了。但是,是因为系统约束(而不是APP的普通行为)导致这个activity被销毁,尽管这个activity实例已经不存在,系统却记得它曾经存在过,这样,如果用户再次通过导航回到它,系统会通过销毁它时保留下来的状态数据创建一个新的实例。这些被保存的,系统用来恢复之前状态的数据被叫做实例状态(instance state),它时存在Bundle对象中的键值对的集合。

注意:用户每次旋转屏幕时,你的activity都会被销毁和重新创建。当屏幕改变方向时,系统会销毁并重新创建前台activity,因为屏幕配置已经改变,你的activity可能需要加载替代资源(比如布局)。

  默认情况下,系统在你的activity布局(比如EditText对象中输入的文本值)中使用Bundle实例来存储每个视图的信息。所以,如果你的activity被销毁并重现创建,你不必用代码来把布局恢复到之前的状态。但是,你的activity中可能会有更多你想要存储的状态信息,比如activity中追踪用户进度的成员变量。

Note:为了让Android系统存储你的activity中每个视图(View)的状态,每个视图必须拥有一个唯一的ID,通过android:id属性来实现。

  为了保存有关activity状态的额外变量,你必须重写onSavedInstanceState()方法。当用户离开你的activity时,系统会调用这个方法,并把它传给Bundle对象,而Bundle对象会在activity被意外销毁时被保存下来。如果系统稍后必须必须重新创建这个activity实例,它会把同一个Bundle对象传给onRestoreInstabceState()和onCreate()方法。


图1
图2当系统开始停止你的activity时,它调用onSaveInstanceState()(1),所以你必须你想要保存的额外数据,以防activity实例被重新创建。如果activity被销毁并且同一个实例必须被重新创建,系统会把定义在(1)中的状态数据同时传给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()方法,这样可以保证默认的实现方法可以保存视图不同层次的状态。

恢复你的Activity

  你的activity之前已经被销毁,当它被重新创建时,你可以从系统传给你的Bundle对象中恢复之前保存的状态。onCreate()方法和onRestoreInstanceState()方法都会接收到同一个Bundle对象,这个对象包含着实例的状态信息。

  不管新建一个activity实例还是从根据之前的实例重新创建一个,系统都会调用onCreate()方法,你必须在读取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
    }
    ...
}

  系统会在onStart()方法之后调用onRestoreInstanceState()方法,你可能会选择实现这个方法而不是在onCreate()方法中恢复状态。仅当有被保存的状态时,系统才会调用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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值