Android Jetpack | Lifecycle

一.前言

  • 本篇主线包含三点,Lifecycle的作用、简单使用、核心原理(包含核心类与源码主线分析);

二.作用

  • 官方文档
  • 生命周期感知型组件可执行操作来响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。这些组件有助于您写出更有条理且往往更精简的代码,这样的代码更易于维护。

三.使用

3.1.依赖

  • 仅针对 lifecycle-common-java8 依赖方式(另一种依赖其实现细节方面的区别在于使用了反射相关的逻辑,将一个方面梳理清楚,另一个方面只要具备了反射相关的知识,分析就比较容易)进行分析,适用于Java8及以上环境
    def lifecycle_version = "2.9.2"implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

3.2.代码

  • 新建TestObserver类
public class TestObserver implements DefaultLifecycleObserver {private static final String TAG = "TestObserver ";@Overridepublic void onCreate(@NonNull LifecycleOwner owner) {Log.d(TAG, "onCreate: ");}@Overridepublic void onStart(@NonNull LifecycleOwner owner) {Log.d(TAG, "onStart: ");}@Overridepublic void onResume(@NonNull LifecycleOwner owner) {Log.d(TAG, "onResume: ");}@Overridepublic void onPause(@NonNull LifecycleOwner owner) {Log.d(TAG, "onPause: ");}@Overridepublic void onStop(@NonNull LifecycleOwner owner) {Log.d(TAG, "onStop: ");}@Overridepublic void onDestroy(@NonNull LifecycleOwner owner) {Log.d(TAG, "onDestroy: ");}
}
  • MainActivity类中添加getLifecycle().addObserver(new TestObserver());
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);getLifecycle().addObserver(new TestObserver());}
}

3.3.好处

  • 当MainActivity生命周期函数,onCreate、onStart、onResume、onPause、onStop、onDestroy被调用时,会触发TestObserver类中对应的回调函数。如果不使用Lifecycle,则写出的代码明显没有这种方式简洁和便于管理。

四.实现原理

  • 为什么按照上面的方式来写就能实现生命周期感知呢?接下来是我们需要探讨的内容。上方所依赖的版本是基于观察者模式实现的。我们先梳理出核心类以及被观察者、观察者、建立被观察者和观察者之间的联系。

4.1.核心类

  • LifecycleOwner 接口

    • MainActivity间接继承的类-ComponentActivity中实现的接口;
  • LifecycleObserver 接口

    • TestObserver间接实现的接口(DefaultLifecycleObserver实现的接口);
  • LifecycleRegistry 类

    • 聚合多个 LifecycleObserver ,生命周期改变时通知 LifecycleObserver 进行相应的方法调用;
    • 该类在ComponentActivity中有对应的成员变量
    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    
  • ObserverWithState 类

    • LifecycleRegistry 中的内部类,对LifecycleObserver进行包装;

4.2.观察者模式的角色及联系方式

  • 被观察者:直接或间接实现LifecycleOwner接口;
    • 即:MainActivity类;
  • 观察者:直接或间接实现LifecycleObserver接口;
    • 即:TestObserver类;
  • 被观察者和观察者建立关联:调用Lifecycle的addObserver函数,函数参数为观察者对象;

4.3.触发逻辑

  • 被观察者的生命周期函数发生变化时通知观察者

4.4.源码分析

  • 目标:只分析主干,梳理Lifecycle的实现原理即可;
  • 以addObserver函数作为分析的入口。

4.4.1.对应LifecycleRegistry类中的addObserver函数

@MainThread
actual override fun addObserver(observer: LifecycleObserver) {enforceMainThreadIfNeeded("addObserver")val initialState = if (state == State.DESTROYED) State.DESTROYED else State.INITIALIZEDval statefulObserver = ObserverWithState(observer, initialState)//注释1val previous = observerMap.putIfAbsent(observer, statefulObserver)//注释2//...
}
  • 注释1,ObserverWithState 类是对observer的包装
  • 注释2,observerMap:这个类是一个自定义列表,用于保存观察者并可在遍历期间处理删除/添加,对应LifecycleRegistry类中的成员变量
private var observerMap = FastSafeIterableMap<LifecycleObserver, ObserverWithState>()

4.4.2.以onCreate函数作为触发条件进行分析

  • 在分析触发条件之前,先分析相关的初始化工作
  • 在ComponentActivity类的onCreate函数
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {//...ReportFragment.injectIfNeededIn(this);//...
}
  • ReportFragment.injectIfNeededIn(this)代码。
    • 这里做了一个区分,当大于等于API29时,通过注册回调的方式。低于则使用无页面的Fragment(ReportFragment);
@JvmStatic
public fun injectIfNeededIn(activity: Activity) {if (Build.VERSION.SDK_INT >= 29) {// On API 29+, we can register for the correct Lifecycle callbacks directlyLifecycleCallbacks.registerIn(activity)}val manager = activity.fragmentManagerif (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {manager.beginTransaction().add(ReportFragment(), REPORT_FRAGMENT_TAG).commit()manager.executePendingTransactions()}
}
  • 不论是哪一种API都会执行到下面的方法,参数1是ReportFragment 当前关联的 Activity,参数2是Lifecycle中定义的枚举事件,在4.4.3中单独分析;
@JvmStatic
internal fun dispatch(activity: Activity, event: Lifecycle.Event) {if (activity is LifecycleRegistryOwner) {activity.lifecycle.handleLifecycleEvent(event)return}if (activity is LifecycleOwner) {val lifecycle = (activity as LifecycleOwner).lifecycleif (lifecycle is LifecycleRegistry) {lifecycle.handleLifecycleEvent(event)}}
}
  • 总结:

    • 无UI的ReportFragment使用了6个生命周期函数onActivityCreated、onStart、onResume、onPause、onStop、onDestroy,调用dispatch函数,分别传入不同的Event。因为Fragment生命周期函数与Activity生命周期函数调用时机的关系,无UI的ReportFragment的生命周期函数的调用约等于Activity几个函数的调用。
    • 而LifecycleCallbacks对Activity生命周期函数的触发做了监听。
  • 综上:当Activity的onCreate函数调用时,则会发送Lifecycle.Event.ON_CREATE事件来调用internal fun dispatch(activity: Activity, event: Lifecycle.Event)函数。其它几个事件同理,到此,触发条件我们也就梳理清楚了。

4.4.3.状态机

  • 学习Lifecycle的核心原理,对状态机部分的了解是必不可少的。4.4.2中所提到的Lifecycle.Event是Lifecycle中定义的枚举事件,Lifecycle中除了定义Event还定义了State,Event和State(对应矩形标记的内容)的对应关系,称为状态机(根据Event推算State,或根据State推算Event,从左往右是UI从不可见到可见的方向,反之,由可见到不可见的方向),如下图所示:
    在这里插入图片描述

4.4.4.继续分析dispatch(activity: Activity, event: Lifecycle.Event)函数

  • 根据上方代码可以知道,activity is LifecycleOwner & lifecycle is LifecycleRegistry 是成立的,执行LifecycleRegistry类的handleLifecycleEvent函数。
public actual open fun handleLifecycleEvent(event: Event) {enforceMainThreadIfNeeded("handleLifecycleEvent")//根据事件,先得到当前activity应该出现的下一个状态moveToState(event.targetState)
}private fun moveToState(next: State) {//...sync()//重点关注//...
}//作用:同步生命周期状态,当被观察生命周期发生改变时,通知所有的观察者进行同步
private fun sync() {val lifecycleOwner =lifecycleOwner.get()?: throw IllegalStateException("LifecycleOwner of this LifecycleRegistry is already " +"garbage collected. It is too late to change lifecycle state.")        while (!isSynced) {newEventOccurred = falseif (state < observerMap.eldest()!!.value.state) {backwardPass(lifecycleOwner)}val newest = observerMap.newest()if (!newEventOccurred && newest != null && state > newest.value.state) {forwardPass(lifecycleOwner)}}newEventOccurred = false_currentStateFlow.value = currentState
}
  • 分析:isSynced
private val isSynced: Booleanget() {//没有观察者时返回trueif (observerMap.size() == 0) {return true}//获取最先添加进来的观察者生命周期状态val eldestObserverState = observerMap.eldest()!!.value.state//获取最后(最近)添加进来的观察者生命周期状态val newestObserverState = observerMap.newest()!!.value.state//如果最先的和最后的Observer的状态一致 && 当前Observer的状态和state保存的状态一致时,返回true,否则就返回falsereturn eldestObserverState == newestObserverState && state == newestObserverState}
  • 观察者具体同步逻辑在backwardPass和forwardPass中,分析其中一个即可
private fun forwardPass(lifecycleOwner: LifecycleOwner) {@Suppress()//使用observerMap 返回一个按添加顺序遍历的迭代器val ascendingIterator: Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> =observerMap.iteratorWithAdditions()while (ascendingIterator.hasNext() && !newEventOccurred) {//从 Map.Entry 中提取,observer为ObserverWithState 对象,封装了观察者及其当前状态val (key, observer) = ascendingIterator.next()while (observer.state < state && !newEventOccurred && observerMap.contains(key)) {pushParentState(observer.state)val event =Event.upFrom(observer.state)?: throw IllegalStateException("no event up from ${observer.state}")//调用observer(即:ObserverWithState 对象)的dispatchEvent函数observer.dispatchEvent(lifecycleOwner, event)popParentState()}}
}
  • 分析observer(ObserverWithState).dispatchEvent(lifecycleOwner, event)
internal class ObserverWithState(observer: LifecycleObserver?, initialState: State) {var state: Statevar lifecycleObserver: LifecycleEventObserverinit {//下方分析lifecycleObserver = Lifecycling.lifecycleEventObserver(observer!!)state = initialState}fun dispatchEvent(owner: LifecycleOwner?, event: Event) {val newState = event.targetStatestate = min(state, newState)//调用lifecycleObserver的onStateChanged函数lifecycleObserver.onStateChanged(owner!!, event)state = newState}}
  • 分析lifecycleObserver = Lifecycling.lifecycleEventObserver(observer!!) & lifecycleObserver的onStateChanged函数
//Lifecycling类中
public actual fun lifecycleEventObserver(`object`: Any): LifecycleEventObserver {val isLifecycleEventObserver = `object` is LifecycleEventObserverval isDefaultLifecycleObserver = `object` is DefaultLifecycleObserverif (isLifecycleEventObserver && isDefaultLifecycleObserver) {return DefaultLifecycleObserverAdapter(`object` as DefaultLifecycleObserver,`object` as LifecycleEventObserver)}if (isDefaultLifecycleObserver) {//分析DefaultLifecycleObserverAdapterreturn DefaultLifecycleObserverAdapter(`object` as DefaultLifecycleObserver, null)}if (isLifecycleEventObserver) {return `object` as LifecycleEventObserver}val klass: Class<*> = `object`.javaClassval type = getObserverConstructorType(klass)if (type == GENERATED_CALLBACK) {val constructors = classToAdapters[klass]!!if (constructors.size == 1) {val generatedAdapter = createGeneratedAdapter(constructors[0], `object`)return SingleGeneratedAdapterObserver(generatedAdapter)}val adapters: Array<GeneratedAdapter> =Array(constructors.size) { i -> createGeneratedAdapter(constructors[i], `object`) }return CompositeGeneratedAdaptersObserver(adapters)}return ReflectiveGenericLifecycleObserver(`object`)
}
  • 在我们前面所使用的观察者TestObserver是实现了DefaultLifecycleObserver接口,则在lifecycleEventObserver函数中执行的是下方的代码
if (isDefaultLifecycleObserver) {return DefaultLifecycleObserverAdapter(`object` as DefaultLifecycleObserver, null)}
  • 分析DefaultLifecycleObserverAdapter类
internal class DefaultLifecycleObserverAdapter(private val defaultLifecycleObserver: DefaultLifecycleObserver,private val lifecycleEventObserver: LifecycleEventObserver?
) : LifecycleEventObserver {override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {when (event) {Lifecycle.Event.ON_CREATE -> defaultLifecycleObserver.onCreate(source)Lifecycle.Event.ON_START -> defaultLifecycleObserver.onStart(source)Lifecycle.Event.ON_RESUME -> defaultLifecycleObserver.onResume(source)Lifecycle.Event.ON_PAUSE -> defaultLifecycleObserver.onPause(source)Lifecycle.Event.ON_STOP -> defaultLifecycleObserver.onStop(source)Lifecycle.Event.ON_DESTROY -> defaultLifecycleObserver.onDestroy(source)Lifecycle.Event.ON_ANY ->throw IllegalArgumentException("ON_ANY must not been send by anybody")}lifecycleEventObserver?.onStateChanged(source, event)}
}
  • 到此,返回到ObserverWithState中,可以知晓:lifecycleObserver = Lifecycling.lifecycleEventObserver(observer!!) 等价于 lifecycleObserver = DefaultLifecycleObserverAdapter,调用lifecycleObserver.onStateChanged(owner!!, event)时会执行DefaultLifecycleObserverAdapter的onStateChanged函数,该函数中,每一个事件,都会触发一个不同的回调函数,即:对应DefaultLifecycleObserver实现类TestObserver中的,从Activity生命周期的执行到观察者TestObserver对应函数的执行,整个流程分析完毕。

4.5.执行流程

  • 结合源码分析,代码执行流程大体如下
    在这里插入图片描述

五.总结

  • Activity里面lifecycle事件的分发会根据API的不同其实现有差异,大于等于29是采用注册的回调的方式,低于29是使用无UI的ReportFragment来实现lifecycle事件的分发;
  • 宿主的每一个生命周期发生变化的时候会发送一个事件,根据事件推导宿主的状态,所有的观察者根据宿主的状态进行升级或降级以保持同步;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/96093.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/96093.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单片机编程架构

没有最好的程序架构。 只要在项目中实现产品功能并稳定工作&#xff0c;且能在团队内统一应用管理就是最优的程序架构。 一、单片机运行模型&#xff1a; 1.能分配时间的裸机代码 2.FreeRTOS操作系统 代码分层框架&#xff1a; 1.与板关联的底层 2.《驱动底层的驱动层》《中间层…

114. 二叉树展开为链表

题目&#xff1a;给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同。…

【Langchain系列三】GraphGPT——LangChain+NebulaGraph+llm构建智能图数据库问答系统

Langchain二次开发专栏 【Langchain系列一】常用大模型的key获取与连接方式 【Langchain系列二】LangChain+Prompt +LLM智能问答入门 【Langchain系列三】GraphGPT——LangChain+NebulaGraph+llm构建智能图数据库问答系统 【Langchain系列四】RAG——基于非结构化数据库的智能问…

【GNSS定位原理及算法杂记6】​​​​​​PPP(精密单点定位)原理,RTK/PPK/PPP区别讨论

PPP 技术详解&#xff1a;原理、流程与 RTK/PPK 对比 在高精度 GNSS 定位技术体系中&#xff0c;除了 RTK 和 PPK 以外&#xff0c;还有一类无需基站即可实现分米到厘米级定位的方法 —— PPP&#xff08;Precise Point Positioning&#xff0c;精密单点定位&#xff09;。它以…

LeetCode 837.新 21 点:动态规划+滑动窗口

【LetMeFly】837.新 21 点&#xff1a;动态规划滑动窗口 力扣题目链接&#xff1a;https://leetcode.cn/problems/new-21-game/ 爱丽丝参与一个大致基于纸牌游戏 “21点” 规则的游戏&#xff0c;描述如下&#xff1a; 爱丽丝以 0 分开始&#xff0c;并在她的得分少于 k 分时…

Codeforces 盒装苹果

题目来源&#xff1a;问题 - 2107B - Codeforces 这道题其实只需要判断两个要点&#xff0c;首先判断一下最大值-1后与最小值的差值是否>k&#xff0c;这里有个小细节&#xff0c;当有多个最大值时&#xff0c;可以先将一个最大值-1后再排序&#xff0c;判断新数组最大值与最…

数据结构--------堆

目录 二叉树 树的概念与结构 非树形结构&#xff1a; 注意&#xff1a; 树的相关术语 树的表示 孩子兄弟表示法 树形结构实际运用场景&#xff08;拓展&#xff09; 1. 文件系统管理 2. 数据库与索引 3. 编程语言与数据结构 信息组织与展示 1. 思维导图 2. 目录与…

VSCode Cursor 大模型 插件扩展 Kilo Code 配置

1.1 概述 Kilo Code 是一个 VSCode Cursor 插件扩展&#xff0c;提供了对多种 AI 模型的支持&#xff0c;包括 Claude Code 和 Qwen3。通过正确配置 Kilo Code&#xff0c;可以在开发过程中获得更好的 AI 辅助编程体验。 Kilo使用文档&#xff1a;https://kilocode.ai/docs/zh-…

深入解析:Unity、Unreal Engine与Godot引擎中的Uniform变量管理

在现代游戏开发中&#xff0c;Uniform变量是实现高质量图形渲染的关键元素。不同游戏引擎对Uniform变量的管理方式有所不同&#xff0c;了解这些差异可以帮助开发者在选择引擎时做出更明智的决策。本文将深入探讨Unity、Unreal Engine和Godot引擎中Uniform变量的管理方式&#…

遨游旅游天地,开启探索未知的梦幻之旅

你是否也怀揣着一颗对世界充满好奇的心&#xff0c;渴望踏上探索旅游世界的奇妙旅程&#xff1f;旅游&#xff0c;是一场与未知的邂逅&#xff0c;是心灵的一次自由翱翔。想象一下&#xff0c;你置身于神秘莫测的撒哈拉沙漠。当夕阳的余晖洒在连绵起伏的沙丘上&#xff0c;那金…

SConscript 脚本入门教程

第一章&#xff1a;什么是 SCons 和 SConscript&#xff1f;核心概念SCons 是一个现代化的构建工具&#xff0c;用于自动化软件构建过程&#xff0c;类似于 Make 但功能更强大、语法更简洁。SConstruct&#xff1a;是 SCons 的主配置文件&#xff0c;通常在项目根目录&#xff…

【深度学习】PyTorch从0到1——手写你的第一个卷积神经网络模型,AI模型开发全过程实战

引言本次准备建立一个卷积神经网络模型&#xff0c;用于区分鸟和飞机&#xff0c;并从CIFAR-10数据集中选出所有鸟和飞机作为本次的数据集。以此为例&#xff0c;介绍一个神经网络模型从数据集准备、数据归一化处理、模型网络函数定义、模型训练、结果验证、模型文件保存&#…

云计算核心技术之容器技术

一、容器技术 1.1、为什么需要容器 在使用虚拟化一段时间后&#xff0c;发现它存在一些问题&#xff1a;不同的用户&#xff0c;有时候只是希望运行各自的一些简单程序&#xff0c;跑一个小进程。为了不相互影响&#xff0c;就要建立虚拟机。如果建虚拟机&#xff0c;显然浪费就…

微信小程序通过uni.chooseLocation打开地图选择位置,相关设置及可能出现的问题

前言 uni.chooseLocation打开地图选择位置&#xff0c;看官方文档介绍的比较简单&#xff0c;但是需要注意的细节不少&#xff0c;如果没有注意可能就无法使用该API或者报错&#xff0c;下面就把详细的配置方法做一下介绍。 一、勾选位置接口 ①在uniapp项目根目录找到manif…

从财务整合到患者管理:德国医疗集团 Asklepios完成 SAP S/4HANA 全链条升级路径

目录 挑战 解决方案 详细信息 Asklepios成立于1985年&#xff0c;目前拥有约170家医疗机构&#xff0c;是德国大型私营诊所运营商。Asklepios是希腊和罗马神话中的医神。 挑战 Asklepios希望进一步扩大其作为数字医疗保健集团的地位。2020年9月&#xff0c;该公司与SNP合作…

高频PCB厂家及工艺能力分析

一、技术领先型厂商&#xff08;适合高复杂度、高可靠性设计&#xff09;这类厂商在高频材料处理、超精密加工和信号完整性控制方面具备深厚积累&#xff0c;尤其适合军工、卫星通信、医疗设备等严苛场景&#xff1a;深南电路&#xff1a;在超高层板和射频PCB领域是行业标杆&am…

AJAX 与 ASP 的融合:技术深度解析与应用

AJAX 与 ASP 的融合:技术深度解析与应用 引言 随着互联网技术的不断发展,AJAX(Asynchronous JavaScript and XML)和ASP(Active Server Pages)技术逐渐成为构建动态网页和应用程序的重要工具。本文将深入探讨AJAX与ASP的融合,分析其原理、应用场景以及在实际开发中的优…

MuMu模拟器Pro Mac 安卓手机平板模拟器(Mac中文)

原文地址&#xff1a;MuMu模拟器Pro Mac 安卓手机平板模拟器 MuMu模拟器 Pro mac版&#xff0c;是一款MuMuPlayer安卓模拟器&#xff0c;可以畅快运行安卓游戏和应用。 MuMu模拟器Pro搭载安卓12操作系统&#xff0c;极致释放设备性能&#xff0c;最高支持240帧画面效果&#…

Oracle维护指南

Part 1 Oracle 基础与架构#### **1.1 概述** - **Oracle 数据库版本历史与特性对比** - **版本演进**&#xff1a; - Oracle 8i&#xff08;1999&#xff09;&#xff1a;支持 Internet 应用&#xff0c;引入 Java 虚拟机&#xff08;JVM&#xff09;。 - Oracle 9i&#…

如何为PDF文件批量添加骑缝章?

骑缝章跨越多页文件的边缘加盖&#xff0c;一旦文件被替换其中某一页或顺序被打乱&#xff0c;印章就无法对齐&#xff0c;能立刻发现异常。这有效保障了文件的完整性和真实性。它是纯净免费&#xff0c;不带广告&#xff0c;专治各类PDF盖章需求。用法极简&#xff1a;文件直接…