重学安卓:绝不丢失状态的 Activity 重建机制!

栏目: IOS · Android · 发布时间: 6年前

内容简介:很抱歉上周我因为沉迷代码而忘了发文。今天和大家分享的这篇,原本是《重学安卓》付费专栏连载的第三篇,没想到在我这几天业余时间独立开发的小应用《JDGD》中,连续遇上了 7 处 “状态重建” 的场景!考虑到我在 <掘金> 等热门技术社区 发文的目标是,提供

很抱歉上周我因为沉迷代码而忘了发文。

重学安卓:绝不丢失状态的 Activity 重建机制!

今天和大家分享的这篇,原本是《重学安卓》付费专栏连载的第三篇,没想到在我这几天业余时间独立开发的小应用《JDGD》中,连续遇上了 7 处 “状态重建” 的场景!

考虑到我在 <掘金> 等热门技术社区 发文的目标是,提供 “从 0 到 1”、易于理解和贯通的 摆渡文,致力于为读者拨开迷雾、建立感性认识。

因而 原味的、硬核的、钻研细节的 文章,我多是在小众的付费技术社区发布。对此感兴趣的朋友请不要慌,文末链接给出 :wink:

重学安卓:绝不丢失状态的 Activity 重建机制!

JDGD 的页面结构是,最外层由一个 Activity 装载着一个 ContainerFragment,然后 ContainerFragment 中又装载了 3 个 ChildFragment。相当于是个 3 层嵌套页面结构。

用户平时可以操作的,就是在这 3 个 ChildFragment 之间来回切换。并且当发生旋转屏幕时,来自 3 个层次的 5 个页面都会发生重建。

重学安卓:绝不丢失状态的 Activity 重建机制!

这要是换做以前的话,我八成是会被难住,因为我司的产品,手机端是固定竖屏,平板端是固定横屏,即使开启了旋转屏幕模式,也不会走重建的流程,因而多年来我都没有钻研过这个问题。

并且,网络上关于重建的文章 多是人云亦云、含糊不清,并没有把最关键的细节给讲明白、讲透,导致我最开始也在 半吊子文章中 白费不少时间。

重学安卓:绝不丢失状态的 Activity 重建机制!

好在上上星期,我亲自复盘和实证了 “状态重建” 的知识点,于是这回遇上的几个问题,都是轻轻松松地得到化解 :wink:。

考虑到页面重建和状态管理,真的是每个人都必然会遇到的问题,于是我就 破例 地将 Activity 状态重建的知识,无保留地分享给大家。

已经付费的小伙伴们请不要担心,今天仅仅是通过介绍 Activity 的重建,来奠定对重建的认知基础, 真正的好戏还在后头 ~

还没阅读过的小伙伴也不要着急,正由于今天讲的是基础, 即使只看这篇,你也没有白来 !:wink:

前言

很高兴见到你!

上一期,我在发表的 《重学安卓:Activity 生命周期的 3 个辟谣》 中,通过介绍网上 99% 的文章都不曾解析过的 “进程模式”,来帮助大家深入理解 Activity 生命周期 的设计依据、存在意义 及 注意事项。

并且,文末我还针对网文的 3 个讹传,来给大家辟了谣。

相信经过这样一次介绍,你对生命周期拥有了相比其他人更加深刻的认识。:wink:

那么这一期,我们来结合现实的案例,来讲解一下 Activity 的重建机制。

文章目录一览

  • 前言
  • 因为心里没底,而不敢用的状态恢复
  • 什么是重建?引发重建的场景有哪些?
  • 为何要设计出重建的机制?有何好处?
  • 状态保存和恢复的具体过程?(99% 的网文遗漏的关键细节)
  • 状态保存和恢复的的注意事项?
  • 如何避免 “配置发生变化” 导致的重建?
  • 综上

因为心里没底,而不敢用的状态恢复

就在上周五,我司向客户推送了 App 新版本,原以为万事大吉,毕竟经过了一周的打磨,各项功能都已趋于流畅稳定,没想到,在客户近乎变态的数据操作下,有客户反映 “页面切换巨卡”、“速度巨慢”。

重学安卓:绝不丢失状态的 Activity 重建机制!

为何会产生这种情况呢?我找到编写该页面的同事询问了缘由。

同事说,问题在于每次 onPause 时,为了避免App 切到后台被系统回收导致数据丢失,而做了大量的数据持久化操作。

那为什么不直接通过 Activity 的状态管理机制 来管理临时数据呢?

同事说,那东西“不靠谱”,用着感觉心里没底。

重学安卓:绝不丢失状态的 Activity 重建机制!

…… 是网上介绍 Activity 重建流程和状态管理的文章不够多吗?不是的,网文都有提到:当发生重建时,就会走 onSaveInstanceState 和 onRestoreInstanceState,

然而却没有一篇深入地探究过:当走 onSaveInstanceState 和 onRestoreInstanceState 时,过程中究竟经历了哪些细节、背后 决定状态被成功保存和恢复的关键条件 到底是怎样的。

这使得读者在使用这个机制时忐忑不安,无法 100% 确定不会出事。

重学安卓:绝不丢失状态的 Activity 重建机制!

于是在经过源码分析和再三的实测检验后,我将 “重建机制” 及 “状态管理机制” 的内容整理成这篇文章。

如果阅读完本文后,你对二者的缘起、规律有了明确的认识,从而 100% 放心地在日后工作中使用,那我的这番功夫就没白费 ~

什么是重建?引发重建的场景有哪些?

正常的生命周期流程,是页面从正常创建到销毁全流程。

而重建流程,则是在特定条件下,引发页面被销毁,并再次被创建的流程。

通常是 “系统资源的回收” 或 “配置发生变化” 导致的重建。

划重点 :point_up_2: :point_up_2: :point_up_2:

系统资源回收是指:

当 App 处于背景模式时,可能因系统内存不足而被回收。

例如按下 Home 键切回桌面,或是接电话跳转到电话程序,都有可能使此前的这个 App 处于背景模式。

配置发生变化是指:

当系统配置发生变化时,比如屏幕方向、语言的改变。

为何要设计出重建的机制?有何好处?

一来:对于资源回收的情况,保存状态并等到使用时再恢复,要比后台存留进程 所占的资源要小得多

二来:对于配置变化的情况,比如当屏幕方向发生变化时, 唯有重建,才有机会加载不同的视图 ,如果横竖屏的布局不同的话。

状态保存和恢复的具体过程?

首先,“状态” 是指支撑 UI 界面内容展示的临时数据。

比如 EditText 中的文本、CheckBox 的勾选与否。

有且只有引发重建时,Activity 会走 onSaveInstanceState 和 onRestoreInstanceState,来保存和恢复状态。

onSaveInstanceState 执行在 onStop 之前,onRestoreInstanceState 执行在 onStart 之后。

其次,Activity 有两个数据结构用于保存状态:

一个是 View States,专门用于存储 View 的状态;

再一个是 Instance States,用于存储 View States 以及 开发者在 onSaveInstanceState 中手动保存的 Activity 成员变量。

重学安卓:绝不丢失状态的 Activity 重建机制!

在引发重建时,Activity 会自动为我们保存和恢复 View 的状态。 具体表现为:

Activity 在 onSaveInstanceState 时,会 自动收集 View Hierachy 中每一个 “实现了状态保存和恢复方法” 的 View 的状态 ,这些状态数据会在 onRestoreInstanceState 时回传给每一个 View。 并且回传时是依据 View 的 id 来逐一匹配的。

划重点 :point_up_2: :point_up_2: :point_up_2:

其中,View 的状态数据会被收集到 View States 中,View States 也会随着 Activity 中其他被指定收集的成员变量,一同被收集到 Instance States 中,等待恢复时逐个恢复。

状态保存和恢复的的注意事项?

简言之:

1.为了成功保存状态,要求在 View 内部实现状态保存和恢复方法。

原生的 View 都有做到;如果是自定义 View,务必记住这一点;如果第三方 View 没做到,可以通过继承其来实现保存和恢复方法。

2.为了成功恢复状态,要求在布局中给 View 赋予相应的 id。

划重点 :point_up_2: :point_up_2: :point_up_2:

3.如果是 Activity 的成员变量,需要额外在 Activity(子类)中重写 onSaveInstanceState 和 onRestoreInstanceState 方法。

注意:

Activity 中重写仅仅是为了额外地保存成员变量。重写方法时,记得要保留基类(super)的实现, Activity 正是在基类中完成 View 状态的保存和恢复

划重点 :point_up_2: :point_up_2: :point_up_2:

如何避免 “配置发生变化” 导致的重建?

在清单文件中为该 Activity 配置 android:configChanges 属性。

比如属性值 orientation|screenSize 对应着旋转屏幕,locale 对应着语言变化。

如此,在配置发生变化时,不会导致重建,而是走 onConfigurationChanged 回调。

综上

只要遵循 《状态保存和恢复的的注意事项》一节所提到的关键细节,就能稳妥地保存和恢复状态。

你再也不用为了临时数据而在 onPause 或 onStop 中执行重量级的持久化存储操作啦!

重学安卓:绝不丢失状态的 Activity 重建机制!

《重学安卓》系列文章

重学安卓:Activity 的快乐你不懂!

重学安卓:Activity 生命周期的 3 个辟谣

重学安卓:绝不丢失状态的 Activity 重建机制!

重学安卓:你丢了 offer,只因拎不清 Activity 任务和返回栈

...


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Transcending CSS

Transcending CSS

Andy Clarke、Molly E. Holzschlag / New Riders / November 15, 2006 / $49.99

As the Web evolves to incorporate new standards and the latest browsers offer new possibilities for creative design, the art of creating Web sites is also changing. Few Web designers are experienced p......一起来看看 《Transcending CSS》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器