Activity生命周期详解(四)

来源:互联网 发布:听百家讲坛的软件 编辑:程序博客网 时间:2024/04/28 03:57

四、重新创建activity
有几个场景中,activity是由于正常的程序行为而被Destroy的,例如当用户点击返回按钮或是activity通过调用finish()来发出停止信号。系统也有可能会在activity处于stop状态且长时间不被使用,或是在前台activity需要更多系统资源时关闭后台进程,以图获取更多的内存。

当activity是因为用户点击Back按钮或是activity通过调用finish()结束自己时,系统就会丢失了对activity实例的引用,因为这一行为意味着不再需要这个activity了,然而,如果因为系统资源紧张而导致activity的Destroy,系统会在用户回到这个activity时有这个activity存在过的记录,系统会使用那些保存的记录数据(描述了当activity被Destroy时的状态)来重新创建一个新的activity实例,那些被系统用来恢复之前状态而保存的数据叫做“instance state”, 它是一些存放在Bundle对象中的key-values pairs(请注意这里的描述,这对理解onSaveInstanceState执行时刻很重要)

Caution:你的activity会在每次旋转屏幕时被destroyed与recreated。当屏幕改变方向时,系统会Destroy与Recreate前的activity,因为屏幕配置的改变,你的activity可能需要加载另一些替代的资源(例如layout)

默认情况下,系统使用Bundle实例来保存每一个View(视图)对象中的信息(例如输入EditText中的文本内容)
因此,如果activity被destroyed与recreated,则layout的状态信息会自动回复到之前的状态。然而,activity也许存在更多你想要恢复的状态信息,例如,记录用户Progress的成员变量(member variables)

Note: 为了使Android系统能够恢复activity中的View状态,每个View都必须有一个唯一ID。由android:id定义

为了可以保存额外更多的数据到saved instance state。在activity的生命周期里面存在一个额外的回调函数,你必须重写这个函数。该回调函数并没有在前面课程的图片示例中显示,这个方法是onSaveInstanceState(),当用户离开activity时,系统会调用它。当系统调用这个函数时,系统会在activity被异常Destroy时传递Bundle对象,这样我们就可以增加额外的信息到Bundle中并保存到系统中,若系统在activity被Destroy之后,onRestoreInstanceState()方法与onCreate()方法中

这里写图片描述

Figure2. 当系统开始停止activity时,只有在activity实例会需要重新创建的情况下才会调用到onSaveInstanceState(1)。在这个方法里面可以指定额外的状态数据到Bundle中如果这个activity被destroyed然后这个实例又需要被重新创建时,系统会传递在(1)中的状态数据到onCreate(2)与onRestroreInstanceState(3)
( 通常来说,跳转到其它的activity或点击Home都会导致当前的activity执行onSaveInstanceState,因为这种情况下的activity都是有可能会被destroy并且是需要保存状态以便后续恢复使用 ,而从跳转的activity点击back回到前一个activity,那么跳转的activity是执行退栈的操作,所以这种情况下是不会执行onSaveInstanceState的,因为这个activity不可能存在需要重建的操作)

2.保存activity状态

当我们的activity开始stop,系统会调用onSaveInstanceState(), activity可以用键值对的集合来保存状态信息。这个方法会默认保存activity视图的状态信息,如在EditText组件中的文本或ListView的滑动位置。

为了给activity保存额外的状态信息,你必须实现onSaveInstanceState()并增加key-value pairs到Bundle对象中,例如:

staticfinal String STATE_SCORE = "playerScore";staticfinal String STATE_LEVEL = "playerLevel";...@Overridepublic void onSaveInstanceState(Bundle savedInstanceState){    // Save the user current 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);}

Cauthion:必须要调用onSaveInstanceState()方法的父类实现,这样默认的父类实现才能保存视图状态的信息。

3.恢复activity状态

当activity从Destroy中重建,我们可以从系统传递的activity的Bundle中恢复保存的状态。onCreate()与onRestoreInstanceState()回调方法都接收到了同样的Bundle,里面包含了同样的实例状态信息。

由于onCreate()方法会在第一次创建新的activity实例与重新创建之前被Destroy的实例时被调用,我们必须在尝试读取Bundle对象前检测它是否为null。如果它为null,系统则是创建一个新的activity实例,而不是恢复之前被Destroy的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    }    ...}

我们也可以选择实现onRestoreInstanceState(),而不是在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);}

Caution:与上面保存一样,总是需要调用onRestoreInstanceState()方法的父类实现,这样默认的父类实现才能保存视图状态的信息。更多关于运行时状态改变引起的recreate我们的activity。请参考 Handling Runtime Changes

0 0
原创粉丝点击