读完本文大概需要花费6分钟。

本文由我的一位读者「MeloDev」独家授权投稿,这个知识点堪称面试常问的基础知识点之一,建议多读几遍,一定理解掌握。微信不支持外链,可点击「阅读原文」查看。

写在前面

在我们的APP使用的过程中,总有可能出现各种手滑、被压在后台、甚至突然被杀死的情况。所以对APP中一些临时数据或关键持久型数据,就需要我们使用正确的方式进行保存或恢复。

突发情况都有哪些

因为本文讨论的是当一些突发情况的出现时,对数据的保存和恢复。所以现在总结一下突发情况应该都有哪些?

  • 点击back键

  • 点击锁屏键

  • 点击home键

  • 其他APP进入前台

  • 启动了另一个Activity

  • 屏幕方向旋转

  • APP被Kill

当这些突发情况发生的时候,有哪些关键的方法会被调用呢?

写了一个简单的demo,我用上述的突发情况进行测试,代码中我重写了所有Activity的生命周期方法和onSaveInstanceState方法,并打印对应的log在控制台,下面是demo图:

这里就不贴出测试的过程了,直接来告诉大家测试的结果吧:

当我的APP处在前台,能与用户交互的情况下,出现上述的突发事件时,只有点击back键,onSaveInstanceState方法不会调用。其余的情况下, 该方法一律都会调用,这又是为什么呢?并且onPause方法是必然会调用的,这又给我们保存数据提供了怎样的思路呢?

onSaveInstanceState

好吧,相信当你看到本文标题的时候,你就应该想到了这个方法。因为当我们学习Android基础知识时,用onSaveInstanceState方法进行数据恢复是你必然学到过的。所以前面我营造出的一些悬念看似是失败了,不过对于onSaveInstanceState你理应知道更多知识:

1. 何时调用:

Android calls onSaveInstanceState() before the activity becomes vulnerable to being destroyed by the system, but does not bother calling it when the instance is actually being destroyed by a user action (such as pressing the BACK key)

找到了以上一段话,翻译过来就是当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。

结合我们以上的例子,其实都在说明一个词,就是被动。当Activity并不是由我主动点击back键而丧失焦点时,onSaveInstanceState方法就一定会调用。就例如我上述列举的那些除了点击back键的「突发情况」

2. 何地调用:

在我写的这个demo中,onSaveInstanceState的调用是处于onPause和onStop之间的,(下面关于Activity的生命周期方法,会讲解一些值得大家注意的),我查阅了一下资料,能保证的是onSaveInstanceState方法会在onStop之前调用,但是是否在onPause之前就不一定了。

结论: google工程师们对onSaveInstanceState如此设计就是让其完成对一些临时的、非永久数据存储并进行恢复。什么样的数据属于临时数据呢?举个例子,比如EditText中输入的内容,CheckBox是否勾选,ScrollView的滑动位置,目前视频的播放位置等等。

当我还没有自学Android时,玩着一些APP就会产生一个疑问,比如我在一个输入框中输入了大量文字没有提交或者保存。此时来了一个电话,如果退回的时候,输入框里面的文字消失了,那我可能会砸了电话,所以这个保存数据的操作,是Android开发者做的吗?

然而是不需要的,因为Android的View本身自己就实现了onSaveInstanceState方法,这些控件自己就具有保存临时数据和恢复临时数据的能力。

例如TextView中的部分源码:

其他View控件都有相似的实现原理。值得一提的是,只有当你给这个wiget在xml中指定id时,它才具有保存数据并且恢复的能力,并且不同的wiget还不能共用这个id,否则会出现数据覆盖的情况。具体的源码有兴趣大家可以自己去看,这里因为篇幅的原因不再贴出,关于onSaveInstanceState我们先说这些,赶紧看看使用姿势。

onSaveInstanceState的使用姿势

比如我们要保存当前视频的播放进度,这个显然控件没有帮我们实现onSaveInstanceState,所以就只能靠自己了,代码如下所示。

当在onCreate取出临时数据时,记得加一个非空判断。

看到这里,也许你认为本文该就此结束了,不过在回过头看看,我们刚才一直强调的是临时数据,毕竟onSaveInstanceState本身就是为临时数据服务的,但是一些永久性质的数据,比如插入数据库的操作,我们应该在什么方法中对其进行保存呢?

onPause

在介绍onPause方法之前,还是想聊聊Activity的生命周期方法,相信大家对它应该有了初步的了解,不过在相应的生命周期方法中,我们应该做什么操作呢?推荐给大家一篇文章,我觉得不错。

「Activity生命周期详解」

关于onPause,我找到了一下关于它的特性:

onPause(), onStop(), onDestroy() are "killable after" lifecycle methods. This indicates whether or not the system can kill the process hosting the activity at any time after the method returns, without executing another line of the activity's code. Because onPause() is the first of the three, once the activity is created, onPause() is the last method that's guaranteed to be called before the process can be killed—if the system must recover memory in an emergency, then onStop() and onDestroy() might not be called. Therefore, you should use onPause() to write crucial persistent data (such as user edits) to storage. However, you should be selective about what information must be retained during onPause(), because any blocking procedures in this method block the transition to the next activity and slow the user experience.

翻译过来就是:无论出现怎样的情况,比如程序突然死亡了,能保证的就是onPause方法是一定会调用的,而onStop和onDestory方法并不一定,所以这个特性使得onPause是持久化相关数据的最后的可靠时机。当然onPause方法不能做大量的操作,这会影响下一个Activity入栈。

刚才我们的测试结果还说明了一个道理,onSaveInstanceState并不是百分百调用的(比如点击了back键),显然一些永久性的数据,我们并不能在此中保存。

关于本文的结论就显而易见了,我们来一句话总结一下:

临时数据使用 onSaveInstanceState 保存恢复,永久性数据使用 onPause 方法保存。


昨天幸运地两位用户为「浅析」、「隐蔽起来」,请这两位读者加我微信,发我收货地址,免费获取我签名的一本书籍。

昨天有人留言说书不重要,重要的是签名,妈蛋,差点我就信了?下次只抽奖一张我签名的纸你们愿意么?

我发现了,赞赏送一个问题的福利有些人还是蛮喜欢的,干脆周末了,想问我问题的赞赏 2.33 元我会回复你的,到时候你可以问我一个问题,只有一个问题哦,锻炼下你提问的技术,周末我抽时间回答你的疑问,平时太忙不会有这个福利,只有周末牺牲下自己的时间帮你们解答下。

别觉得亏了,记得你的赞赏是支持我的原创分享而已,这个福利只是额外赠送的。另外我的时间比这值钱多了好么?没问题的忽略,赞赏金额随意,一块也是对我的支持,坚持原创分享真心不易!

Android中突发情况数据的保存和恢复相关推荐

  1. Android中突发情况数据的保存

    Android中突发情况数据的保存 本文原创,转载请获得本人准许. 写在前面: 在我们的APP使用的过程中,总有可能出现各种手滑.被压在后台.甚至突然被杀死的情况.所以对APP中一些临时数据或关键持久 ...

  2. Android中清除应用数据的方法

    Android 中应用的数据分为内置储存的和外置储存,默认是保存在内置储存的,所以一般清除内置储存的就行了.使用这个工具类: import java.io.File;public class Data ...

  3. Android中使用的数据单位

    Android中使用的数据单位 px(Pixels,像素):对应屏幕上的实际像素点. in(Inches,英寸):屏幕物理长度单位. mm(Millimeters,毫米):屏幕物理长度单位. pt(P ...

  4. 【译】Android中的安全数据— Android中的加密(第1部分)

    目录 Java密码体系结构 Android Key Store 样例项目 下一步是什么 安全提示 Java密码体系结构 Android建立在Java密码体系结构(JCA)的基础上,该体系结构提供了用于 ...

  5. 【译】Android中的安全数据— Android中的加密(第2部分)

    目录 锁屏 选择一个钥匙 密钥存储 密钥生成 密钥管理 加密与解密 使用范例 下一步是什么 安全提示 锁屏 如果要保护数据,请保护设备. 为了更加安全,在提供对任何应用程序功能的访问权限之前,我们可以 ...

  6. android https详解,如何使用HTTPS和HTTP来解析Android中的JSON数据?

    我跟随this到Parse Json在Android中 我用HttpData处理程序成功完成了它. 在这里,我成功将数据发布到服务器并获得响应.. 现在我想在HTTPS的一部分中使用它. 可以任何人建 ...

  7. node sqlite 插入数据_安卓手机中的应用数据都保存在哪些文件中?

    随笔 知识 案例 声音 其他 编者按 手机取证,品牌是一方面,从操作系统入手是另外一个渠道.手机中的重要数据基本上都以轻量数据库的形式保存在本地,也就是经常讲的sqlite db文件中. 从推特上得知 ...

  8. 模拟Android内存不足 activity回收 值保存 状态恢复

    作者简介 微信公众号(高质量文章推送):陈博易 作者:陈博易 声明:本文是个人原创,未经允许请勿转载 商业合作请在微信公众号回复:联系方式 **## 前言 1.我记得我实习的那会,面试官问我关于aci ...

  9. 【译】Android中的安全数据-初始化向量

    目录 初始化向量 默认值 自订值 空值 随机加密 使用范例 下一步是什么 安全提示 初始化向量 初始化向量是加密原语的固定大小输入.通常要求它是随机或伪随机的.IV的重点是允许使用相同的密钥来加密几个 ...

  10. Android中wifi与数据流量的切换监听

    最近在做一个wifi和移动数据的监控功能,来来回回折腾了一阵子,这个模块的主要功能是监听整个APP的wifi与数据流量的切换,让用户使用专用流量,而不是用wifi,给一个弹窗,点击确认,自动切换数据流 ...

最新文章

  1. python 实现延迟的操作
  2. 【Android】基于A星寻路算法的简单迷宫应用
  3. 原生 遍历_细品原生JS从初级到高级知识点汇总(三)
  4. Happy new year 2009
  5. Matlab | Matlab从入门到放弃(2)——索引
  6. boost::intrusive::avl_set用法的测试程序
  7. ES6基础5(Promise)-学习笔记
  8. 电离辐射防护与辐射源安全基本标准_漳武南靖段A1项目成功举办桥面系 安全防护标准化观摩会...
  9. 删除Autorun.inf的方法
  10. 如何打通“鱼塘” ?腾讯启动“SaaS技术联盟” 共建技术中台
  11. 4一20ma电流有源与无源区别_【知识分享】信号的有源与无源(2)
  12. 管理后台--3,修改分类
  13. mysql获取分组后每组的最大值
  14. Kafka副本同步机制理解
  15. Android APP完整基础教程(01)开发环境简介
  16. 详细解读TPH-YOLOv5 | 让目标检测任务中的小目标无处遁形
  17. Spring blunder
  18. c语言 main()可否省略,main函数中省略返回语句
  19. 手把手教你入门深度强化学习(附链接代码)
  20. shiro权限控制登陆成功页面跳转问题

热门文章

  1. poj 1679(次小生成树)
  2. SOA进入成熟应用阶段仍需时日
  3. Spring.Web 之双向数据绑定(Bidirectional data binding)
  4. exce小技巧,Mac Excel单元格内换行快捷键
  5. SMART Utility for mac (硬盘检测工具)
  6. Mac优化工具多合一MacCleaner PRO
  7. kotlin版本组件化+mvvm项目架构
  8. MPAndroidChart 2.15使用记录
  9. linux下安装mysql-5.7.20
  10. 百万级别长连接,并发测试指南