Activity被系统意外回收时保留临时数据的方法onSaveInstanceState(Bundle outState)

onSaveInstanceState(Bundle outState)用于在系统由于内存紧张而回收程序的内存等情况时保存一些关键数据,对应的恢复数据函数为onRestoreInstanceState(Bundle savedInstanceState),也可以在函数onCreate(Bundle savedInstanceState)中来恢复数据。onSaveInstanceState通常在onPause()之后调用,但如果是按返回键等情况显式退出程序,则不会调用。保存及恢复数据时都用到一个Bundle对象,类似于一个map,可以存入键值对信息,但即使onSaveInstanceState调用了,也不保证之后重新进入程序会调用onRestoreInstanceState,同时onCreate中的Bundle对象也可能为null,只有当程序在后台运行时内存确实被系统回收了或者是横竖屏切换等情况,再次重新进入程序时,onCreate函数中的Bundle对象才不为null,并且存储了之前在onSaveInstanceState用户放入的数据,而onRestoreInstanceState函数也通常会在onResume()执行之前被调用。可以在onStop()函数中加入以下代码模拟程序被系统回收:   
   new Handler().post(new Runnable() {
        publicvoid run() {
           // TODO Auto-generated method stub
           Runtime.getRuntime().exit(1);
        }
      });
在覆写onSaveInstanceState函数时记得调用父类对应函数,即super.onSaveInstanceState(),因为父类此函数的作用是保存android提供的各个view类如EditText等的数据,android的每个view类都提供了保存自己数据的函数,例如在EditText中输入了文本,这个文本数据会被存储下来,而这个存储行为是在super.onSaveInstanceState()中被执行的,同时,此EditText还需要在布局属性中加入id属性,否则数据无法被保存。同样在覆写onRestoreInstanceState函数时也要调用super.onRestoreInstanceState()函数,其对应着执行恢复EditText等android的View类的数据。

上述内容提到在横竖屏切换时会调用onSaveInstanceState,但这也是有条件的,当程序配置了对手机特定配置改变如横竖屏切换等的处理,即在manifest文件中activity标签下加入了android:configChanges="orientation|screenSize"(API 13以后需要这样配置),那么由于在横竖屏切换时只会调用onConfigurationChanged(Configuration newConfig)函数,而不会调用activity的任何生命周期函数,onSaveInstanceState函数也就不会被调用了。

实例:活动被系统意外回收时_保留临时数据onSaveInstanceState(Bundle outState)

public class MainActivity extends Activity
{
    private EditText et;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //
        //小技巧:
        //MainActivity.this.getClass().getName().toString()----------<package name>.<instance name>
        //MainActivity.this.getClass().getSimpleName().toString()----<instance name>
        //
        Log.e(MainActivity.this.getClass().getSimpleName().toString(), "开始了");
        et = (EditText) findViewById(R.id.et);
        if(savedInstanceState != null)
        {    
            String tempData = savedInstanceState.getString("key");//temp 临时的
            et.setText(tempData);
            et.setSelection(tempData.length());
        }
    }
    
    @Override
    protected void onSaveInstanceState(Bundle outState)//state 国家 规定 情形 n/v
    {
        super.onSaveInstanceState(outState);
        String tempData = et.getText().toString();
        outState.putString("key", tempData);
    }
}
【注意】:

API 21为Activity增加了一个新的属性,只要将其设置成persistAcrossReboots,activity就有了持久化的能力,另外需要配合一个新的bundle才行,那就是PersistableBundle。 

onCreate(Bundle savedInstanceState, PersistableBundle persistentState)

Same as onCreate(android.os.Bundle) but called for those activities created with the attribute persistableMode set to persistAcrossReboots.


这里的持久化与传统意义的不同,它的具体实现在Activity重载的onSaveInstanceState、onRestoreInstanceState和onCreate方法。

public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState)

public void onRestoreInstanceState(Bundle savedInstanceState, PersistableBundle persistentState)

public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState)

onSaveInstanceState和onRestoreInstanceState方法是一对拯救灾难的方法,它们不在“正常“的Activity生命周期中,只有一些突发异常情况才会触发它们,比如横竖屏切换、按Home键等。当API 21后增加了PersistableBundle参数,令这些方法有了系统关机重启后数据恢复的能力。

只需在Manifest中的activity设置属性 (此处有一个坑,在API 21及以上,若使用了上述三个方法,则必须在Manifest中设置此属性,否则布局控件将不能显示,Activity将不能正常运行,生命周期方法调用异常)

android:persistableMode="persistAcrossReboots"

然后在activity中直接用上述的三个方法即可。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值