【Android Developers Training】 18. 重新创建

系统 1627 0

注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。

原文链接: http://developer.android.com/training/basics/activity-lifecycle/recreating.html


在应用被正常使用的情况下,会有一些场景发生并使得你的activity被销毁,比如:当用户按下了返回键,或者你的activity调用了 finish() 方法将自己销毁。当你的 activity 处于停止态且已经很久没有被使用的情况下,系统也会将它销毁。还有一种情况是处于前台的 activity 需要更多的资源,此时系统必须将一部分后台进程停止来释放出一些内存空间。

当你的activity因为用户按下了返回键或者自己调用了finish()将自己销毁时,该 Activity 的实例将不再存在,因为导致其被销毁的行为暗示了这个activity已经不再需要了。然后如果是由于系统资源紧张而被迫将Activity销毁(非正常的应用行为),那么虽然 Activity 的实例已经不再了,当用户回到这个 Activity 时,系统仍然会记得它其实是存在的。此时,系统会利用该 Activity 被销毁时所保存的描述其状态的数据集,来创建一个新的 Activity 实例。这些系统用来恢复之前状态的数据被称作为“ 实例状态(instance state) ”,它实质上是一个存储于一个 Bundle 对象的键值对数据集合。

Caution:

每次用户旋转了屏幕后,你的activity都会被销毁和重新创建。这样做的原因是因为屏幕的旋转会导致屏幕参数的变化(长和宽互换),此时你的activity可能需要加载一些可选的资源(比如针对于横屏或竖屏下的布局)

默认的,系统使用 Bundle 实例状态 来保存你的activity布局中每个 View 对象的信息(比如在 EditText 对象中输入的文字)。所以,如果你的activity实例被销毁和重新创建,布局的状态会恢复到之前的状态,且你不需要为此编写代码。然而,你的activity可能会有更多你希望存储的状态信息,比如一些用来追踪用户进度的成员变量。

Note:

为了让Android系统恢复activity中的view状态, 每个View必须有一个独有的ID ,这个ID由属性字段“ android:id ”提供。

为了存储更多关于activity状态的数据,你必须覆写 onSaveInstanceState() 回调函数。当用户离开你的activity时系统会调用该方法,并且传递给他一个 Bundle 对象,存储数据以防activity被意外地销毁了。之后如果系统必须重新创建这个activity实例,它会把相同的 Bundle 对象传递给 onRestoreInstanceState() 方法和 onCreate() 方法。

图1. 当系统要停止你的activity时,它会调用 onSaveInstanceState() 方法(1),所以你可以指定你先要存储的额外数据,当activity被重新创建时会用到它们。 如果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);

}
      
    

Caution:

必须调用父类的 onSaveInstanceState() ,这样默认的实现会保存View的状态

 

二). 恢复你的Activity状态

当你的Activity在之前被销毁后需要被重新创建时,你可以通过系统传递给Activity的 Bundle 对象来恢复之前的状态。 onRestoreInstanceState() 方法和 onCreate() 方法都会接受到相同的 Bundle 对象,其中包含了实例的状态信息。

因为不管是系统在创建一个新的实例还是重新创建一个旧的, onCreate() 都会被系统调用,所以在你尝试读取 Bundle 之前,必须检查它是否是null。如果是null,那么系统会创建一个新的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 是否是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() ,这样默认的实现会恢复View的状态

如果想要学习关于在运行时由于重启事件导致activity被重新创建(如旋转了屏幕),可以阅读: Handling Runtime Changes

【Android Developers Training】 18. 重新创建一个Activity


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论