Activity被回收怎么办?带你解析onSaveInstanceState的源码

今日科技快讯

近日有消息称:招商银行上海川北支行6月26日向上海市高级人民法院申请财产保全,请求冻结乐视相关公司及贾跃亭夫妇资产共计12.3亿元,或查封、扣押其他等值财产。对此乐视相关负责人表示:“招行申请的资产冻结,起因是一笔乐视手机业务融资贷款。但我们针对此笔贷款的资产抵押,足够覆盖债务。公司高层也正在与招商银行在内的各金融机构紧密沟通中,希望尽快解决相关债务问题。”

作者简介

本篇是 马伟奇 的投稿,分享了 onSaveInstanceState源码内核分析,希望能够帮助到大家。

马伟奇 的博客地址:

http://www.jianshu.com/u/53e5012c55a3

正文

经常有人问,后台的 activity 被系统自动回收的话,怎么回到界面的时候恢复数据,通过一个真实案例给大家讲讲如何保存状态,然后带着大家分析 onSaveInstanceState 的源码。

当前页面侧滑菜单指向专题,用户做了如下操作:

  • 当用户按下 HOME 键时。

  • 长按 HOME 键,选择运行其他的程序时。

  • 按下电源按键(关闭屏幕显示)时。

  • 从activity A中启动一个新的 activity 时。

  • 屏幕方向切换时,例如从竖屏切换到横屏时。

失去焦点,activity 很可能被进程终止!被 KILL 掉了,这时候就需要能保存当前的状态,不然下次用户再次进来看到的还是新闻,这样用户体验就不够好,代码有删减,我自己项目就这样使用的,解决方案如下:

如上代码可知:
界面被回收之后调用 onSaveInstanceState 方法保存当前的状态,每个侧滑菜单选项都有一个位置。
由以上代码可知:

判断当前 Bundle 是否有刚刚我们保存的位置,如果不为空,从当前的 Bundle 取出来,给每一个位置赋值。

以上代码可知:

根据当前的位置设置到 adapter 当中,这样下次用户进来就还是专题了。

总结下 savedInstanceState 的使用,代码如下:

横竖屏切换,打印结果如下:

从打印结果可以看出来,当前 Activity 被系统回收之后,会调用 onSaveInstanceState() 保存状态,然后在 activity 判断 bundler 是否有当前状态,如果只是到这,估计你们就会吐槽没啥含金量,没办法硬着头皮上,接着咱们来分 onSaveInstanceState() 源码,请看如下代码:

以上代码可知

调用父类 Activity 源码里面的 onSaveInstanceState 方法,代码如下:

以上代码可知
  • outState.put 一个 tag 调用了 mWindow 里面的 saveHierarchyState 方法,继续分析Window源代码。

  • window 是抽象类调用子类 PhoneWindow 里面的 saveHierarchyState 方法代码如下:

以上代码可知
  • Bundle outState = new Bundle() 初始化 Bundle 对象,Bundle 实现了 Parcelable 接口。

  • states = new SparseArray<Parcelable>() 并且把自己放到 outState 当中。

  • mContentParent.saveHierarchyState(states),整个 View 树的顶层视图保存了层级状态代码如下:

以上代码可知:

调相应的 dispatchSaveInstanceState 方法,代码如下:

以上代码可知:

  • 原来 NO_ID 用来标记没有 id 的 View,搜索 mID 可知原来在如下代码赋值

经常当我们看不懂谷歌源码的时候,可以通过曲线救国的方式,看看英文注释,看看源码哪个地方用到当前的类或者方法或者变量,这样就好理解了,好了扯远了,继续分析代码;

  • 通过if判断,检测子类是否调用父类的 onSaveInstanceState() 方法,否则会抛异常,突然看到这才明白,还记得刚刚开始学 Android 的时候,经常一不小心就把代码里面的 super.onCreate(savedInstanceState); 这行代码删掉,报了错误还看不懂,原来系统在这里检测了,都怪自己曾经太年轻。

  • container.put(mID, state) 这行代码,将 state 放进 SparseArray 中,以 view 自身的 id为 key,并且从注释来看打印 mID 的 Hex 值用来保证每页的 id 必须是唯一的,难怪每当我给 view 取 id 的时候,一个页面有重复的 id 就会报错,谷歌大婶在这里做判断了,腻害了 word 哥,总是百思不得其姐,凭啥不让我共用 id (因为取名字太难了),原来是想把 id 做为 key 来使用。

  • 走到这 onSaveInstanceState(),调用如下代码:

以上代码可知:

设置位标志, 默认不 save 任何东西,状态为空,这就是为啥我们每次随便写个类继承  activity实现 onCreate 方法的时候可以使用参数 savedInstanceState 保存状态,因为默认为 null,代码如下:

至此整个 savedInstanceState 保存状态源码分析完毕。

更多

每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。

如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。

欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值