zoukankan      html  css  js  c++  java
  • 保存和恢复activity的状态数据[转]

    转自:here

    一般来说,调用onPause()和onStop()方法后的activity实例仍然存在于内存中,activity中的所有信息和状态数据都不会消失,当activity重新回到前台后,所有的改变都会保留。

    但是当内存系统内存不足时,调用onPause()和onStop()方法的activity可能被摧毁。此时内存中就不会存在有该activity实例对象了。

    为了避免这种情况,我们可以覆盖onSaveInstanceState()方法来接受一个Bundle类型的参数,我们可以将该activity的信息和状态数据存入此Bundle中。这样,即使该activity在后台被系统摧毁,然后重新回到前台的时候,在调用onCreate()方法时,该Bundle对象会传入onCreate方法的参数中。开发者可以在onCreate中取出自己保存的数据。

     1 public class MainActivity extends Activity {
     2     public static final int SECOND_ACTIVITY = 0;
     3     private String temp;
     4 
     5     @Override
     6     public void onCreate(Bundle savedInstanceState) {
     7         super.onCreate(savedInstanceState);
     8         // 从savedInstanceState中恢复数据, 如果没有数据需要恢复savedInstanceState为null
     9         if (savedInstanceState != null) {
    10             temp = savedInstanceState.getString("temp");
    11             System.out.println("onCreate: temp = " + temp);
    12         }
    13     }
    14 
    15     public void onResume() {
    16         super.onResume();
    17         temp = "xing";
    18         System.out.println("onResume: temp = " + temp);
    19         // 切换屏幕方向会导致activity的摧毁和重建
    20         if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
    21             setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    22             System.out.println("屏幕切换");
    23         }
    24     }
    25     
    26     // 将数据保存到outState对象中, 该对象会在重建activity时传递给onCreate方法
    27     @Override
    28     protected void onSaveInstanceState(Bundle outState) {
    29         super.onSaveInstanceState(outState);
    30         outState.putString("temp", temp);
    31     }
    32 }
     1 @Override
     2     protected void onRestoreInstanceState(Bundle savedInstanceState) {
     3         UtilsLog.i(tag, "onRestoreInstanceState");//onStart调用了此方法
     4         super.onRestoreInstanceState(savedInstanceState);
     5     }
     6     @Override
     7     protected void onResume() {
     8         UtilsLog.i(tag, "onResume");
     9         super.onResume();
    10     }
    11     @Override
    12     protected void onSaveInstanceState(Bundle outState) {
    13         UtilsLog.i(tag, "onSaveInstanceState");// 在onPause之后调用
    14         /**
    15          * 当activity再次启动时,这个Bundle会传递给onCreate()方法和随着onStart()方法调用的onRestoreInstanceState(),<br>
    16          * 所以它们两个都可以恢复捕获的状态
    17          */
    18         super.onSaveInstanceState(outState);
    19     }
    20     @Override
    21     protected void onPause() {
    22         super.onPause();
    23         /**
    24          * onPause()是三个中的第一个,它也是唯一一个在进程被杀死之前必然会调用的方法──onStop() 和 onDestroy() 有可能不被执行。<br>
    25          * 因此应该用 onPause() 来将所有持久性数据(比如用户的编辑结果)写入存储之中。
    26          */
    27         UtilsLog.i(tag, "onPause");
    28     }

    需要注意的是, onSaveInstanceState()方法并不是一定会被调用的, 因为有些场景是不需要保存状态数据的. 比如用户按下BACK键退出activity时, 用户显然想要关闭这个activity, 此时是没有必要保存数据以供下次恢复的, 也就是onSaveInstanceState()方法不会被调用. 

    onSaveInstanceState()方法的默认实现

    如果开发者没有覆写onSaveInstanceState()方法, 此方法的默认实现会自动保存activity中的某些状态数据, 比如activity中各种UI控件的状态. android应用框架中定义的几乎所有UI控件都恰当的实现了onSaveInstanceState()方法, 因此当activity被摧毁和重建时, 这些UI控件会自动保存和恢复状态数据. 比如EditText控件会自动保存和恢复输入的数据, 而CheckBox控件会自动保存和恢复选中状态. 开发者只需要为这些控件指定一个唯一的ID(通过设置android:id属性即可), 剩余的事情就可以自动完成了. 如果没有为控件指定ID, 则这个控件就不会进行自动的数据保存和恢复操作.

    由上所述, 如果开发者需要覆写onSaveInstanceState()方法, 一般会在第一行代码中调用该方法的默认实现: super.onSaveInstanceState(outState).

    是否需要覆写onSaveInstanceState()方法

    既然该方法的默认实现可以自动的保存UI控件的状态数据, 那什么时候需要覆写该方法呢?

    如果需要保存额外的数据时, 就需要覆写onSaveInstanceState()方法. 如需要保存类中成员变量的值(见上例).

    onSaveInstanceState()方法适合保存什么数据

    由于onSaveInstanceState()方法方法不一定会被调用, 因此不适合在该方法中保存持久化数据, 例如向数据库中插入记录等. 保存持久化数据的操作应该放在onPause()中. onSaveInstanceState()方法只适合保存瞬态数据, 比如UI控件的状态, 成员变量的值等.

    引发activity摧毁和重建的其他情形

    除了系统处于内存不足的原因会摧毁activity之外, 某些系统设置的改变也会导致activity的摧毁和重建. 例如改变屏幕方向(见上例), 改变设备语言设定, 键盘弹出等.

  • 相关阅读:
    软件工程个人作业(4)
    软件工程个人作业(3)
    软件工程个人作业(2)
    软件工程个人作业(1)
    构建之法
    消息分发机制,实现战场与UI通信功能
    设置父物体方法(包括层级)
    NGUI通过点击按钮来移动面板位置,实现翻页功能
    unity中调用android的剪切板
    屏蔽UI事件
  • 原文地址:https://www.cnblogs.com/wangziqiang/p/3861459.html
Copyright © 2011-2022 走看看