Activity : 状态保存与恢复

当系统内存不足时,系统会强制结束一些不可见的Activity以节省内存资源。在某些情况下,当被强制结束的Activity再次显示时会出现一些问题。
例如:一个APP有2个Activity界面:Activity1 和 Activity2。用户在Activity1填写了一些数据后跳转到了Activity2,Activity2完全把Activity1遮盖了起来。当系统资源不足时,被Activity2完全遮盖住的Activity1也有可能被系统干掉。如果发生了这种情况,当用户在Activity2折腾了一番又点击返回按钮想返回Activity1时,就可能会有一些问题了。因为Activity1已经被系统强制销毁了,用户之前在Activity1填写的数据已经不存在了。所以Activity类中还提供了onSaveInstanceState() 和 onRestoreInstanceState() 2个方法可以用来解决这个问题。
1、onSaveInstanceState() 
onSaveInstanceState() 方法用来在Activity被强制销毁之前保存数据,onSaveInstanceState()方法会携带一个 Bundle类型的参数,Bundle提供了一系列的方法用于保存数据,比如可以使用 putString()方法保存字符串,使用 putInt()方法保存整型数据。每个保存方法需要传入两个参数,第一个参数是键,第二个参数是真正要保存的内容。

2、onRestoreInstanceState()
onSaveInstanceState() 方法用来取得之前在onSaveInstanceState() 保存的值。
另外,除了onRestoreInstanceState()可以取得onSaveInstanceState() 保存的值之外,onCreate()函数也可以取得保存的值,这些值就存在onCreate()函数的参数savedInstanceState里,在哪个函数取出这些值就要看具体的需求了。


【举个栗子】

我们继续使用 Activity : 生命周期 的代码,稍加改造一下。

1、在Activity1.Java追加2个函数

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("key1", "value1");
    super.onSaveInstanceState(outState);
    Log.i("INFO", "Activity1: onSaveInstanceState, key1[value1]");
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    Log.i("INFO", "Activity1: onRestoreInstanceState, key1[" + savedInstanceState.getString("key1") + "]");
}

修改Activity1.Java的onCreate()函数中的log输出代码为

if(savedInstanceState != null) {
    Log.i("INFO", "Activity1: onCreate, key1[" + savedInstanceState.getString("key1") + "]");
}
else {
    Log.i("INFO", "Activity1: onCreate");
}

2、在Activity2.Java追加2个函数

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("key1", "value1");
    super.onSaveInstanceState(outState);
    Log.i("INFO", "Activity2: onSaveInstanceState, key1[value1]");
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    Log.i("INFO", "Activity2: onRestoreInstanceState, key1[" + savedInstanceState.getString("key1") + "]");
}

</pre><pre>

修改Activity2.Java的onCreate()函数中的log输出代码为

if(savedInstanceState != null) {
    Log.i("INFO", "Activity2: onCreate, key1[" + savedInstanceState.getString("key1") + "]");
}
else {
    Log.i("INFO", "Activity2: onCreate");
}

3、在Activity3.Java追加2个函数

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("key1", "value1");
    super.onSaveInstanceState(outState);
    Log.i("INFO", "Activity3: onSaveInstanceState, key1[value1]");
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    Log.i("INFO", "Activity3: onRestoreInstanceState, key1[" + savedInstanceState.getString("key1") + "]");
}
修改Activity2.Java的onCreate()函数中的log输出代码为
if(savedInstanceState != null) {
    Log.i("INFO", "Activity3: onCreate, key1[" + savedInstanceState.getString("key1") + "]");
}
else {
    Log.i("INFO", "Activity3: onCreate");
}


然后启动程序,观察log输出。

1、跳转到ACTIVITY2时

Activity1: onPause
Activity2: onCreate
Activity2: onStart
Activity2: onResume
Activity1: onSaveInstanceState, key1[value1]
Activity1: onStop

从ACTIVITY2返回ACTIVITY1时

Activity2: onPause
Activity1: onCreate
Activity1: onStart
Activity1: onResume
Activity2: onSaveInstanceState, key1[value1]
Activity2: onStop

2、跳转到ACTIVITY3时

Activity1: onPause
Activity3: onCreate
Activity3: onStart
Activity3: onResume
Activity1: onSaveInstanceState, key1[value1]
从ACTIVITY3返回ACTIVITY1
Activity3: onPause
Activity1: onResume
Activity3: onStop
Activity3: onDestroy
3、打开对话框 和 从对话框返回ACTIVITY1时(没有LOG输出)
4、按桌面按钮返回桌面时:
Activity1: onPause
Activity1: onSaveInstanceState, key1[value1]
Activity1: onStop
从桌面再次打开APP时:
Activity1: onRestart
Activity1: onStart
Activity1: onResume
5、锁屏时:
Activity1: onPause
Activity1: onSaveInstanceState, key1[value1]
Activity1: onStop
解锁时:
Activity1: onRestart
Activity1: onStart
Activity1: onResume
6、横屏竖屏切换时(Ctrl + F12)
Activity1: onPause
Activity1: onSaveInstanceState, key1[value1]
Activity1: onStop
Activity1: onDestroy
Activity1: onCreate, key1[value1]
Activity1: onStart
Activity1: onRestoreInstanceState, key1[value1]
Activity1: onResume

从上面的log可以看出:

发生1和2这种Activity间跳转时,被遮盖的Activity的onSaveInstanceState()函数被调用,Activity的临时数据被保存了起来。上面的log中没有读取被保存的数据,是因为系统没有发生内存不足的情况,被遮盖的Activity还没有被销毁。

返回桌面、锁屏两种情况也是保存了数据却没有读取数据,同理也是系统还没有销毁被遮盖的Activity。

横屏竖屏切换时,因为Activity肯定会被销毁然后重新创建,所以Activity的数据保存和读取都发生了,这种情况日常很常见,比如:

使用优酷等视频APP看视频时我们经常会在横屏和竖屏间切换(看视频:横屏,中途来了电话:竖屏,接完电话继续看视频:横屏),当切换横竖屏时,正在观看中的视频并没有从头播放,而是从中断处继续播放,这就是因为横竖屏切换时视频的播放进度被事先保存了起来,当切换完成后取出之前保存的进度,继续播放。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值