onPause() v.s. onSaveInstanceState()

onPause() 和 onSaveInstanceState() 中都可以保存 Activity 的数据,那二者在使用时有什么不同呢?

首先,我们为什么要保存数据?

  • 持久化草稿
    将草稿保存到手机存储卡上,待用户下次打开 app 时继续编辑;
  • 保存状态
    用户 Activity A 中点击了 tab、输入了文本,然后跳到 B,内存紧张导致 A 被系统回收或者干脆 B 直接 crash 了,用户再回到 A 时,为了达到连贯的用户体验我们需要恢复 Activity 的原貌:包括文本输入框中的文字和 tab 的选中状态,这要求我们在跳到 B 前保存文本数据和临时状态数据(tab的选中状态);
  • 横竖屏切换前后,界面的样子要保持一致;



Activity 的2种死法:

  • 正常死亡
    是指完美享受了生命的各个阶段,最后走到了生命的尽头 —— onDestroy() 里面;
    出现场景:用户按 Back 键;
  • 非正常死亡
    是指尚未走进 onDestroy() 就被系统“谋杀”,即,在 onPause() 或 onStop() 阶段由于更高优先级的进程需要内存(见上图),所以被系统杀死;
    出现场景:红米1手机上实际可用内存非常小,经常出现后台 APP 被杀死的情况;

也就说,Activity 被销毁前,一定会经历 onPause() 阶段,不一定会经历 onDestroy()。

onSaveInstanceState() 呢?
在正常死亡情况下,如从 Activity B 返回到 Activity A,B 的 onSaveInstanceState() 方法不会被调用。此时,A 的界面由系统保持原样,包括滚动文位置、输入框内的文本等。

在非正常死亡情况下,onSaveInstanceState() 保证在 onStop() 之前被调用,至于和 onPause() 的先后关系——可能在之前,也可能在之后。

在移动设备上打字是一件很痛苦的事,不管 Activity 怎么死的,在死之前,我们都应当把用户辛辛苦苦输入的文本/图片保存下来,存到草稿中,持久化到磁盘。

既然 onPause(),onStop(),onSaveInstanceState() 中,只有 onPause() 是百分百被调用的,那肯定是在 onPause() 中保存数据了。

但是,实际开发中,我们并不会在 onPause() 中保存数据,而是监听 Back 键。当用户按下 Back 键时提示时否保存草稿,确定时再保存,保存数据的动作是在 onBackPressed() 里面实现的,就不关 onPause() 啥事了。除非你想做到用户按下 Back 键是应用默默的把内容保存为草稿。而且,由于是用户主动退出,那些状态值就没必要保存了,下次打开 app 展示初始化时的状态。

考虑下非正常死亡的情况。
非正常死亡时,只有 onPause() 和 onSaveInstanceState(Bundle) 肯定会被调用。

非正常死亡之后,当用户又回到该 Activity 时,该 Activity 会被重新创建,为了让用户看到和离开时一样的界面,我们除了要恢复输入框内的文本数据,还要恢复像选中的 tab、列表的滚动位置等着状态。至于恢复的方法,前者是在 onCreate() 方法中从磁盘读取,而后者是没有必要持久在磁盘上的,我们只需在 onSaveInstanceState() 里面保存即可,然后在 onCreate() 或 onRestoreSaveInstance() 中读取。

注意,我们并不知道 onSaveInstanceState() 中保存的 Bundle 是否会被持久化,也许只是保存在内存里。

当然,你也可以在 onSaveInstanceState() 中保存文本数据。比如从 Activity A 跳转到 Activity B,此时 Activity A 被杀死或 Activity B 出现 crash,系统会重新创建 Activity A,为了恢复 A 的原貌,我们需要在 onSaveInstanceState() 中保存需要持久化的数据和状态值,然后在 onCreate() 里面读取出来。

综上,实际开发中,我们一般不在 onPause() 里面而是在 onSaveInstanceState() 里面保存数据(既包括可能需要持久化的,也包括状态值),然后在 onBackPressed() 里面去提示用户是否需要持久化数据,需要的话再去持久化。

onCreate(Bundle) 中的 Bundle 可能是空,而 onRestoreInstanceState(Bundle) 里面的 Bundle 一定是非空的。

参考文章:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值