安卓现代化开发系列——从生命周期到Lifecycle【扩展包1已更新】-2

简介: 安卓现代化开发系列——从生命周期到Lifecycle【扩展包1已更新】

安卓现代化开发系列——从生命周期到Lifecycle【扩展包1已更新】-1

https://developer.aliyun.com/article/1398226


3、谷歌眼中的Lifecycle


3.1、ComponentActivity

此类是谷歌官方基于Activity开发的子类,其集成了许多Jetpack库的核心功能,其中就包括了「Lifecycle」库,该类因此也实现了LifecycleOwner接口,开发者常用的AppcompatActvity也是该类的子类。

image.png

但是细读源码会发现,该类并没有像笔者之前展示的源码那样,直接调用LifecycleRegistry在特定的Activity生命周期回调中派发事件,那么该类是如何实现生命周期事件的派发的呢?下面介绍「Lifecycle」库中的另外一个关键类:ReportFragment


3.1.1、ReportFragment与LifecycleCallbacks

ComponentActivity的onCreate()中,有一段ReportFragment.injectIfNeededIn(this)的代码,这个就是实现了生命周期事件派发的核心类。

image.png

接下来让我们走进ReportFragment的源码,正如前文所述,文章并不会阐述每一行代码的原理,而是抓住主要的脉络,隐藏了和主脉络无关的代码,但是剩余的代码量仍然挺多,读者不必对大量的代码感到恐慌,因为文章会逐一解释:

image.png

image.png

image.png

可见,ReportFragment做的事非常简单,就是在其生命周期的各个阶段上报生命周期事件,因为Fragment的生命周期和Activity在绝大部分是保持一致的(特殊的如onCreate()除外,不过也有onActivityCreated()onActivityPostCreated()等可以感知Activity生命周期的函数),谷歌的开发人员于是就利用ReportFragment作为监听Activity生命周期的工具,你可以看到这个Fragment是没有UI的,这也间接证明了它的任务并不是展示一个UI而仅仅是为了监听生命周期。


让我们回到injectIfNeedIn() ,可以清楚的看到这里做了一个版本判断,如果大于api版本大于29,则使用LifecycleCallbacks做一个注册的逻辑,这是怎么回事呢?

image.png

在我提到ReportFragment是作为一个生命周期监听者而不是一个展示UI的模块的时候,你也许就已经隐隐约约闻到一种非常奇怪的味道。由于安卓源码设计的缺陷(只对外提供了回调方法而没有提供回调监听注册),开发者对待这一问题必须考虑向下兼容,因此他们选择了源码中已经存在的、可以监听Activity的生命周期的Fragment,但是在api 29之后,Activity原生自带了生命周期的回调监听注册,因此一旦检测到api大于或者等于29,ReportFragment的作用就形同虚设了,因为广播生命周期的事件的任务已经转移给Activity自带的生命周期回调来实现了。


你也许还会担心,现在有ReportFragmentActivity自带的生命周期回调两种方式了,会不会导致一个事件被广播两次呢?其实不用担心,广播的时候已经做了排除了,只有api小于29的情况下,ReportFragment才会生效。

image.png


3.2、Fragment

Fragment本身的生命周期和Activity没有很大的差异,依然是内置LifecycleRegistry然后在合适的生命周期回调中广播生命周期事件的一套,但是值得注意的是:


FragmentFragmentManager管理时,例如执行replace()事务中,逻辑上当前的Fragment只是被另外一个同类所替换了,它并没有真的被销毁(因为待会还有重新回来的机会),因此该Fragment并不会执行onDestroy(),然而由于内存上的考量,不可见的FragmentView理应被回收,因此View会被销毁。

换句话说,Fragment不可见之后,它的状态会保存起来,但是其View会被销毁,待会再次可见的时候,会根据其状态再一次执行onCreateView()


上述机制导致了一个问题:Fragment的生命周期和其对应的View的生命周期在实质上是不对等的,然而实际开发中感知生命周期大多数是为了与UI进行互动,这也导致了开发者单纯监听Fragment的生命周期已经不能够满足开发上的需求了。


下面这张来源于谷歌官方开发者文档的图片很好的诠释了Fragment和它的View的生命周期关系:

image.png

假如一个Fragment正在栈顶,他会处于Resumed的阶段,但是被replace之后(或者说是进入了回退栈),它会进入Created阶段,此刻View被销毁,View会进入Destroyed阶段,但是Fragment重回栈顶的时候,Fragment会从Created再次回归到Resume,而View会从Destroyed重回Resumed状态。


换句话说,在Fragment的生命周期中,它的View可能会反复的从Destroyed到Resumed之间移动(即不断地销毁与创建)


谷歌为了缓解这个问题,给FragmentView单独添加了一套生命周期,我们可以通过代码看到端倪:

image.png

可以看到,在Fragment执行performCreateView()的时候,会初始化ViewLifecycle,两者的生命周期事件是单独通知的。

  • 如果开发者想访问Fragment的生命周期,在Fragment中访问lifecycleOwner即可。
  • 如果开发者想访问FragmentView的生命周期,在Fragment中访问viewLifecycleOwner即可。


3.3、ViewTreeLifecycleOwner

在上述的代码中,能够直接访问ActivityFragment的Lifecycle的只能是它们的类中,而很多需要访问生命周期的地方往往是一些View中,例如要在View中监听其父组件生命周期,然而View的父控件有非常多,包括了ActivityFragment甚至是Dialog乃至更多,要想获取父组件的生命周期,只能做类型判断+类型强转的工作,这样就极大的限制了View的使用范围:

image.png

为了缓解,谷歌的开发人员提出了一种叫ViewTreeLifecycleOwner的设计,其实这个东西并没有什么神秘的,让我们直接看看源码:

image.png

通篇只有两个View的扩展函数,第一个函数的意义是给对应的View绑上一个LifecycleOwner,第二个函数的意义是不断往上查找父控件,直到查出之前绑定的LifecycleOwner


这段源码的作用挺简单的,也就是说只要给某个顶层的控件提前绑好了LifecycleOwner,那么他下辖的所有子View都可以通过往上查找的方式来找到LifecycleOwner,不得不说谷歌的开发人员真的是太厉害了,在简陋的基础下做出了非常强大的功能。


那么下面的问题是:LifecycleOwner的绑定发生在哪里呢?


3.3.1、Activity中的绑定

Activity的直接子类ComponentActivityAppcompatActivity均自动完成了绑定的工作,我们以ComponentActivity为例看看相关的绑定代码:

image.png

可见在ComponentActivitysetContentView被执行时,会将ActivityViewLifecycleOwner绑定其所在的WindowDecorView中,我们都知道Activity下面的所有View都是DecorView的子View,因此它们都可以直接通过谷歌开发人员提供的扩展函数直接访问到最顶层的ActivityLifecycle


#3.3.2、Fragment中的绑定

Activity类似,Fragment也采用了几乎一致的绑定方式,只不过是将Lifecycle绑定在了FragmentView之上:

image.png

3.3.3、Dialog中的绑定

默认的DialogActivity是不支持ViewTreeLifecycleOwner的,因此谷歌的开发人员重新继承实现了一个新的Dialog子类:ComponentDialog,其中的绑定大同小异,简单看下源码即可了解:

image.png

看来和Activity一样,把LifecycleOwner绑定在了DecorView中。


3.3.4、意义与总结

那么谷歌的开发人员费尽心思的为以上的组件绑定ViewTreeLifecycleOwner有何用意呢?意义可大了,由于消除了组件之间的差异(均是通过View往上查找父控件直到找到LifecycleOwner的模式),我们不用在乎当前的View是在哪个控件中,都是统一通过findViewTreeLifecycleOwner()来获取最顶层控件的生命周期。


例如下面的自定义View的代码,无论在上述哪个控件中都可以用:

image.png

可见,开发者只需要关注生命周期本身,不再需要担心不同组件之间的差异了。


4、结语


安卓原生的生命周期设计只能说是毛坯房都算不上的水平,然而通过「Lifecycle」库的加持之后,开发者可以轻松访问组件的生命周期,让开发业务更加的合理与安全。


作为开发者的你,应该逐渐将重写生命周期函数的方式逐渐过渡到「Lifecycle」的开发方式中来,在一些工具类亦或者其他业务类中,你也可以使用「Lifecycle」辅助强化与生命周期相关的业务。


如果文章帮助到你,请为笔者点一个👍🏻支持一下,你的鼓励是我前进的动力!


安卓现代化开发系列——从生命周期到Lifecycle【扩展包1已更新】-3

https://developer.aliyun.com/article/1398235?spm=a2c6h.13148508.setting.14.e4774f0eb3rwuq

相关文章
|
2天前
|
JavaScript 前端开发 Java
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
IT寒冬使APP开发门槛提升,安卓程序员需转型。选项包括:深化Android开发,跟进Google新技术如Kotlin、Jetpack、Flutter及Compose;研究Android底层框架,掌握AOSP;转型Java后端开发,学习Spring Boot等框架;拓展大前端技能,掌握JavaScript、Node.js、Vue.js及特定框架如微信小程序、HarmonyOS;或转向C/C++底层开发,通过音视频项目如FFmpeg积累经验。每条路径都有相应的书籍和技术栈推荐,助你顺利过渡。
13 3
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
|
1天前
|
搜索推荐 Android开发 iOS开发
探索安卓与iOS开发的差异性与互补性
【8月更文挑战第19天】在移动应用开发的广阔天地中,安卓与iOS两大平台各据一方,引领着行业的潮流。本文将深入探讨这两个平台在开发过程中的不同之处以及它们之间的互补关系,旨在为开发者提供一个全面的视角,帮助他们更好地把握市场动态,优化开发策略。通过分析各自的开发环境、编程语言、用户界面设计、性能考量及市场分布等方面,我们将揭示安卓与iOS开发的独特魅力和挑战,同时指出如何在这两者之间找到平衡点,实现跨平台的成功。
|
3天前
|
移动开发 开发工具 Android开发
探索安卓与iOS开发的差异:技术选择的影响
【8月更文挑战第17天】 在移动应用开发的广阔天地中,安卓和iOS两大平台各领风骚。本文通过比较这两个平台的编程语言、开发工具及市场策略,揭示了技术选择对开发者和产品成功的重要性。我们将从开发者的视角出发,深入探讨不同平台的技术特性及其对项目实施的具体影响,旨在为即将步入移动开发领域的新手提供一个清晰的指南,同时给予资深开发者新的思考角度。
|
4天前
|
vr&ar Android开发 iOS开发
探索安卓和iOS开发的未来趋势
在移动应用开发的广阔天地里,安卓和iOS两大平台如同双子星座般璀璨夺目。随着技术的不断进步,这两个平台的开发趋势也在悄然发生着变化。本文将带你一探究竟,看看未来安卓和iOS开发将会迎来哪些令人激动的新特性和挑战。让我们一起跟随技术的脚步,开启这场探索之旅吧!
|
5天前
|
移动开发 Java Android开发
安卓与iOS开发:异同探析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文旨在深入探讨这两个平台在开发环境、编程语言、用户界面设计、性能优化及市场分布等方面的异同,为开发者提供实用的比较视角和决策参考。通过对比分析,我们不仅能更清晰地认识到各平台的特性,还能洞察未来移动开发的可能趋势。
|
1天前
|
移动开发 Android开发 iOS开发
揭秘移动开发之谜:安卓与iOS之间的技术鸿沟有多深?探索两大平台的开发差异及其对应用性能和用户体验的惊人影响!
【8月更文挑战第19天】在移动应用开发领域,安卓与iOS占据主导地位。两者在技术架构、开发工具及市场分布上各有特色。本文通过案例对比分析,展示安卓使用Java/Kotlin与iOS采用Swift/Objective-C的语言差异;探讨iOS统一细腻设计与安卓自定义Material Design的UI区别;并讨论安卓广泛市场覆盖与iOS高用户价值对开发者策略的影响。理解这些差异有助于制定有效的开发计划。
|
1天前
|
安全 Android开发 iOS开发
探索安卓与iOS开发的差异:平台特性与用户体验的比较
【8月更文挑战第19天】 在移动应用开发的广阔天地中,安卓与iOS两大平台各领风骚。本文将深入探讨这两个平台在开发过程中的关键差异,从编程语言和工具到用户界面设计,再到市场分布和安全性考虑。我们将一窥究竟,是什么让安卓开发如此灵活多变,又是什么让iOS开发显得精致而统一。通过这篇比较分析,开发者可以更清晰地认识到各自平台的优势和挑战,从而做出更明智的开发决策。
7 0
|
4天前
|
Java Android开发 iOS开发
探索安卓与iOS开发的差异:从新手到专家的旅程
本文将带你走进移动应用开发的两大平台——安卓和iOS,揭示它们之间的主要差异。我们将从新手的视角出发,逐步深入到更复杂的技术层面,帮助你理解这两个平台的开发环境、编程语言和用户界面设计等方面的不同。无论你是刚入门的新手,还是有一定经验的开发者,这篇文章都将为你提供有价值的见解和建议。现在,让我们一起开始这段探索之旅吧!
|
4天前
|
搜索推荐 Android开发 iOS开发
探索安卓与iOS开发的差异之美
在数字时代的浪潮中,移动应用开发如同一场精心编排的交响乐,安卓和iOS这两大平台扮演着不同乐器的角色,各自以独特的方式奏响。本文将带领读者走进这场音乐盛宴,感受两大平台在开发过程中所展现的不同韵律,从设计理念到用户体验,从市场占有率到生态系统,我们将一探究竟,欣赏它们如何在竞争激烈的市场中和谐共存,共同推动技术的进步与创新。
12 0
|
5天前
|
开发工具 Android开发 iOS开发
探索安卓与iOS开发的差异:构建未来应用的关键考量
在数字时代,选择正确的开发平台是成功的一半。本文深入探讨了安卓与iOS两大移动操作系统的开发差异,并分析了各自对创新、用户体验和市场需求的响应。通过比较两者的设计哲学、开发工具、市场覆盖和用户参与度,我们揭示了每个平台的独特优势和潜在挑战,旨在为开发者提供决策时的洞见,帮助他们在竞争激烈的应用市场中做出明智的选择。