zoukankan      html  css  js  c++  java
  • ACTIVITY状态保存

      关于activity的状态保存,以前从来没想过还会有这个问题。这里小小总结一下,以备日后查看。

    系统默认实现了哪些

      1》可以做个测试,我们可以写个demo,界面上有一个EditText。然后你在里面随便填入一些数据。然后按home键回到桌面,这个时候会调用activity的onPause->onStop,然后我们长按home键选择刚才的demo重新打开发现EditText里面的数据并没有丢失。这是因为执行onStop后此activity并没有并销毁,所以它的各种状态也会被保持。

      2》我们接着测试,我们在EditText中填入数据,接着旋转屏幕这个时候会重启activity(系统会先回调onDestory,然后立即回调onCreate)。下面就要分两种情况了:a.如果我们为此EditText在布局文件中设置的有id,这种情况我们会看到此EditText中的数据会被保持 b.若我们没有为此EditText设置id的话,我们会看到旋转屏幕后此EditText里面的内容为空(丢失了)。

    那么为什么为EditText中设置了id的话它的数据会被保存呢?

      Activity中有一个回调方法:protected void onSaveInstanceState(Bundle outState),此方法会默认保存activiy中所有有id的view的信息。比如CheckBox的是否选中的状态等等。保存下来的这些信息会在Activity的另一个回调方法 protected void onRestoreInstanceState(Bundle savedInstanceState) 中恢复.

      总结:

        通过以上的测试可以得出这样的结论:1>只要activity没有被销毁(系统没有回调onDestory),那么它的各种状态就不会丢失。2>若activity由于某种原因(比如旋转屏幕、系统内存紧张)被销毁,则它里面的有id的view的状态将被保存下来。

    以上是系统默认实现好的。

    需要我们自己实现的

      有时候有些信息要我们自己实现保存,防止activity被销毁后信息丢失。比如游戏的进度。假设这样一个场景:我们正在完游戏,然后来了一电话,则游戏将进入后台,又由于手机配置较低或其它的原因,系统杀死了游戏进程。当我们接完电话后,重新回到游戏会发现游戏进度丢失。为了防止这种情况发生,我们应该这样做:

      复写Activity的onSaveInstanceState(Bundle outState)及onRestoreInstanceState(Bundle savedInstanceState)方法,将要保存的信息通过onSaveInstanceState方法的Bundle(关于Bundle这里不多做解释)参数保存。然后在onRestoreInstanceState方法中通过它的Bundle参数savedInstanceState进行恢复即可。完整流程请看下图:

    通过测试可知:onSaveInstanceState一般会在onPause后被回调,onRestoreInstanceState一般会在onResume前被回调

    实例

      

    写个小例子:如上图,其中我们为EditText及button设置的有id而没有为checkBox设置id.在button上,每点击一次增加一次点击次数,我们通过一个全局变量保存点击次数,然后再通过onSaveInstanceState方法的Bundle保存下来,当重新回到Activity时此Bundle会被传给onRestoreInstanceState然后我们在此方法中恢复即可。布局文件如下:

    View Code
     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:orientation="vertical"
     6     tools:context=".ActivityLifeDemo" >
     7 
     8     <EditText
     9         android:id="@+id/finish"
    10         android:layout_width="fill_parent"
    11         android:layout_height="wrap_content" />
    12 
    13     <CheckBox
    14         android:layout_width="fill_parent"
    15         android:layout_height="wrap_content"
    16         android:text="checkBox" />
    17 
    18     <Button
    19         android:id="@+id/clickTimes"
    20         android:layout_width="fill_parent"
    21         android:layout_height="wrap_content"
    22         android:text="你点击了0次" />
    23 
    24 </LinearLayout>

    Activity代码:

    View Code
     1 public class ActivityLifeDemo extends Activity {
     2 
     3     private static final String TAG = "ActivityLifeDemo";
     4 
     5     private int click_time = 0;
     6     Button btn;
     7 
     8     @Override
     9     protected void onCreate(Bundle savedInstanceState) {
    10         super.onCreate(savedInstanceState);
    11         Log.d(TAG, "onCreate");
    12         setContentView(R.layout.activity_activity_life_demo);
    13         btn = (Button) findViewById(R.id.clickTimes);
    14 
    15         btn.setOnClickListener(new OnClickListener() {
    16 
    17             @Override
    18             public void onClick(View v) {
    19                 btn.setText("你点击了" + ++click_time + "次");
    20             }
    21         });
    22 
    23     }
    24 
    25     @Override
    26     protected void onRestoreInstanceState(Bundle savedInstanceState) {
    27         super.onRestoreInstanceState(savedInstanceState);
    28         Log.e(TAG, "onRestoreInstanceState");
    29         click_time = savedInstanceState.getInt("clickTimes");
    30         btn.setText("你点击了" + click_time + "次");
    31     }
    32 
    33     @Override
    34     protected void onSaveInstanceState(Bundle outState) {
    35         super.onSaveInstanceState(outState);
    36         Log.e(TAG, "onSaveInstanceState");
    37         outState.putInt("clickTimes", click_time);
    38     }
    39 
    40     @Override
    41     protected void onStart() {
    42         super.onStart();
    43         Log.d(TAG, "onStart");
    44     }
    45 
    46     @Override
    47     protected void onRestart() {
    48         Log.d(TAG, "onRestart");
    49         super.onRestart();
    50     }
    51 
    52     @Override
    53     protected void onResume() {
    54         Log.d(TAG, "onResume");
    55         super.onResume();
    56     }
    57 
    58     @Override
    59     protected void onPause() {
    60         Log.d(TAG, "onPause");
    61         super.onPause();
    62     }
    63 
    64     @Override
    65     protected void onStop() {
    66         Log.d(TAG, "onStop");
    67         super.onStop();
    68     }
    69 
    70     @Override
    71     protected void onDestroy() {
    72         Log.d(TAG, "onDestroy");
    73         super.onDestroy();
    74     }
    75 
    76 }

    如何测试:

      在EditText中随便输入一些数据,然后选中Checkbox,再点击几次button。然后旋转屏幕。观察哪些数据丢失哪些数据没变。

     结论:会看到Checkbox的信息会丢失,这是因为我们没有为它设置id,EditText的数据不变,button中的点击次数也被保存下来了

    需要注意的地方:

      1》恢复操作也可以在onCreate(它也有一个Bundle参数)中进行,不过还是建议大家在onRestoreInstanceState中进行,这样各个方法的职责更单一

      2》onSaveInstanceState不保证一定会被调用,比如我们点击back键主动关闭activity则系统不会回调onSaveInstanceState方法,此时系统理解我们主动关闭所以不需要保存其状态。因此,对于一些需要持久保存的信息,比如保存到数据库中的不应该写在此方法中写,一般会在onPause中做这些。

      3》当我们覆写onSaveInstanceState及onRestoreInstanceState时不应该删除父类的默认实现,否则就不能实现保存‘有id的view’的信息了

  • 相关阅读:
    vue element-ui 饿了么布局,gutter间距碰上bordr 会失效
    Linux 常用命令
    阿里云部署,ubuntu, 连接服务器 |更新源| 安装node |安装mysql
    常用 shell 命令 chmod | root
    node 进程管理 child_process [spawn,exec] | 珠峰培训node正式课 网络爬虫
    html2canvas用法的总结(转载)
    使用nvm-windows安装nodejs遇到的问题(转载)
    Can’t call setState (or forceUpdate) on an unmounted component 警告处理方法
    webpack 搭建问题汇总
    webpack执行命令参数
  • 原文地址:https://www.cnblogs.com/byghui/p/3073715.html
Copyright © 2011-2022 走看看