码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-04-16 14:41:05      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:就是   undle   ref   位置   自动   并且   注释   content   选项   

  近日有消息称:招商银行上海川北支行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() 并且把自己放到 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 保存状态源码分析完毕。

  更多

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

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

  大连哪家男科医院好 http://www.nk0411.com/

  大连正规妇科医院 http://www.bhyy0411.com/

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

标签:就是   undle   ref   位置   自动   并且   注释   content   选项   

原文地址:https://www.cnblogs.com/lll123/p/10716472.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!