从getLifecycle讲起
查看getLifecycle方法的注释,确定是LifecycleOwner接口定义的,要求实现的,返回一个提供Lifecycle的对象
那还有谁实现了这个接口?可以说可见的界面如Fragment,ComponentDialog跟ComponentActivity都实现了
LifeCycle是什么
是抽象类.定义了一个具有Android生命周期的对象.并提供LifeCycleObserver的管理接口。内部包含State和Event概念,将生命周期函数对应成State,生命周期改变会造成State改变,进而触发Event事件,从而被LifecycleObserver接收。
具体体现就是在Lifycycle接口提供的addObserver跟removeObserver.以及内部枚举类Event跟State,都代表着具备Lifecycle的LifecycleOwner对象的不同状态.
get到的LifeCycle是什么
从上面几个LifecycleOwner接口实现类点击查看,唔,全是LifecycleRegistry.那也就是说提供Lifecycle对象,其实就是LifecycleRegistry.
-
androidx.core.app.ComponentActivity
-
Fragment
-
ComponentDialog
-
androidx.activity.ComponentActivity
-
FragmentViewLifecycleOwner
LifecycleRegistry
作为Lifecycle的实现类,起着添加观察者,响应生命周期事件,分发生命周期事件的作用.
observerMap字段:观察者容器
内部有一个observerMap的字段,是Map吗?不是,是一个实现了Iterator接口的迭代器,对HashMap进行操作.
但我们从addObserver跟removeObserver方法的源码可以看到都是由observerMap来完成,将外部传入的LifecycleObserver包装成ObserverWithState,最终交给其内部的HashMap字段保存,说用HashMap来维护的说法其实也可以.
enforceMainThread字段:线程检测
从构造方法可以得知,还有一个enforceMainThread字段,从字面意思是也能猜到是主线程检测,具体体现在enforceMainThreadIfNeeded方法内,而该方法在其他api操作,如上述addObserver跟removeObserver方法中均会调用进行线程检测,大家知道有这个玩意就行.
但是这跟我们要讨论的生命周期到生命周期事件有什么关系? 因为生命周期触发到事件,正是借助LifecycleRegistry对象的handleLifecycleEvent方法来完成.
handleLifecycleEvent方法:事件传递
这里采用ComponentDialog,Fragment跟FragmentActivity为例子.
触发传递关键点
- 当生命周期变化时,LifeCycleOwner实现类内部由LifecycleRegistry调用handleLifecycleEvent方法为入口调用moveToState到sync方法完成事件接收
- sync方法调用到backwardPass和forwardPass方法遍历observerMap内保存的ObserverWithState(其实也是取出LifecycleObserver来操作)
- 遍历环节取出ObserverWithState调用dispatchEvent方法,内部让LifecycleObserver触发onStateChanged方法.
代码走读
生命周期变化触发LifecycleRegistry的handleLifecycleEvent方法传不同生命周期事件
具体我们一步步点击来看,handleLifecycleEvent方法内先完成线程检测,再开始执行moveToState方法,将生命周期事件的Event内容传入.从上图得知,不同的状态比如onResume,onPause时候都会传不同的Lifecycle.Event事件进来,完成事件处理的环节交给sync方法
sync方法内使用backwardPass和forwardPass这两方法最终以正序倒序遍历mObserverMap的内容
遍历内容
通过触发ObserverWithStatedispatchEvent事件,内部会执行LifecycleEventObserver引用分发event.
至此,我们知道了当LifecycleOwner出现生命周期变化的时候,是如何通知到LifecycleObserver并触发onStateChange事件的.但这里仍然存在几个问题:
- 为什么遍历还需要正序倒序?
- 为什么文章开头所提到的LifecycleOwner没有包含Activity,难道Activity就不能获取到Lifecycle了吗,没法支持addObserver之类的操作了吗?
遍历顺序选择
我们看下判断条件:
这里需要明确:对比的state,是Lifecycle.State,也就是说DESTROYED < INITIALIZED < CREATED < STARTED < RESUMED.这点由在State中定义的顺序来决定.
但是State的值取决于前面提到moveToState方法接收Event的值,从Event取State的逻辑告知了生命周期到State的转变
判断依据
-
state < observerMap.eldest()!!.value.state判断检查当前状态是否小于最早添加的观察者的状态
如果当前 state 是 STARTED,而最早添加的观察者状态是 RESUMED,那么 STARTED < RESUMED 为 true,这时需要执行 backwardPass,将所有观察者状态降级
-
!newEventOccurred && newest != null && state > newest.value.state没有新的事件发生,存在最新添加的观察者的前提下.如果当前 state 是 RESUMED,而最新添加的观察者状态是 STARTED,那么 RESUMED > STARTED 为 true,这时需要执行 forwardPass,将所有观察者状态升级
设计原因
但是这里为什么要有正序和倒序遍历呢? 这涉及到 Lifecycle 状态变化时的一个重要设计原则:绑定通知有序.保证Lifecycle状态变化时 observers 的调用顺序符合以下规则:
- 当 Lifecycle 状态向上升级时(如 CREATED -> STARTED):应该按照 observers 的注册顺序(正序)调用,这样先注册的 observer 会先收到状态升级的通知,这通过forwardPass来实现.
- 当 Lifecycle 状态向下降级时(如 RESUMED -> STARTED):应该按照 observers 的注册顺序的反序(倒序)调用,这样后注册的 observer 会先收到状态降级的通知,这通过backwardPass实现
举例
正在使用一个 ComponentActivity:
- 该Activity处于RESUMED 状态
- 所有观察者都处于RESUMED 状态
state = RESUMEDobserverMap.eldest()!!.value.state = RESUMED
按Home键以后:
- 该Activity会调用 onPause()
- LifecycleRegistry的state变为STARTED
- 此时:
state = STARTED,observerMap.eldest()!!.value.state = RESUMED - 满足
state < observerMap.eldest()!!.value.state条件
所以会触发backwardPass,将所有观察者状态RESUMED降级到STARTED
从后台切回Activity,Activity恢复前台:
- 该Activity 会调用 onResume()
- LifecycleRegistry 的 state 变为 RESUMED
- 此时:
state = RESUMED,observerMap.newest()!!.value.state = STARTED - 满足
state > newest.value.state条件
所以会触发 forwardPass,将所有观察者状态从STARTED升级到RESUMED
添加新观察者后:满足state > newest.value.state条件
所以会触发forwardPass,将新观察者状态从STARTED升级到RESUMED,确保新观察者能立即响应当前的生命周期状态
该Activity 开始销毁:
- 调用 onPause(),state 变为 STARTED
- 满足
state < observerMap.eldest()!!.value.state条件 - 触发backwardPass,将所有观察者状态降级到STARTED
- 然后调用onStop(),state 变为CREATED
- 再次满足降级条件,触发 backwardPass
- 最后调用onDestroy(),state变为DESTROYED
最后一次触发 backwardPass
总结
我们常说的Fragment,ComponentActivity,ComponentDialog里获取的Lifecycle,其实就是LifecycleRegistry
内部提供了hashmap管理保存了观察lifecycle变化的LifecycleObserver
生命周期变化时触发的Event和State变化将遵循向上或者向下的状态遍历,目的是为了实现类似栈的管理,确保观察者有序接收通知