Lifecycle 原理
文章目录
- Jetpack Lifecycle 原理
- 一、核心角色
- 二、生命周期事件与状态的映射
- 三、工作流程
- addObserver()
- 生命周期的传递过程
- 四、关键实现细节
- 1. Activity 如何感知生命周期?
- 2. 添加观察者时(`addObserver`)做了什么?
- 3. 状态同步核心(`sync()`)
- 4. 事件如何到达自定义 Observer?
- 五、面试官可能追问的问题
- 六、总结
Jetpack Lifecycle 原理
一、核心角色
| 角色 | 接口/类 | 职责 |
|---|---|---|
| 被观察者 | LifecycleOwner(接口) | 拥有生命周期,如ComponentActivity、Fragment,对外提供Lifecycle |
| 观察者 | LifecycleObserver(空接口) | 监听生命周期事件,通常使用DefaultLifecycleObserver |
| 桥梁 | Lifecycle(抽象类) | 管理观察者列表、分发事件,具体实现在LifecycleRegistry |
三者的关系:LifecycleOwner 持有并暴露 Lifecycle(一一对应),Lifecycle 维护 LifecycleObserver 以及生命周期的监听 和 生命周期变更事件的派发
📌 本质:观察者模式+状态机,通过抽象解耦。
二、生命周期事件与状态的映射
- State:
DESTROYED、INITIALIZED、CREATED、STARTED、RESUMED(状态是有序的,可比较) - Event:
ON_CREATE、ON_START、ON_RESUME、ON_PAUSE、ON_STOP、ON_DESTROY、ON_ANY
三、工作流程
addObserver()
第一步:包装观察者,确定初始状态
StateinitialState=mState==DESTROYED?DESTROYED:INITIALIZED;ObserverWithStatestatefulObserver=newObserverWithState(observer,initialState);- 根据当前
LifecycleOwner的mState(owner的当前状态)决定新观察者的初始状态。 - 将原始
observer包装成ObserverWithState,内部会通过Lifecycling.lifecycleEventObserver()把观察者转换成统一的LifecycleEventObserver(封装了状态)
(适配器模式, 让LifecycleRegistry可以用标准、简单的方式分发事件,而不用关心观察者具体是怎么实现的)。
第二步:存入 Map,去重
ObserverWithStateprevious=mObserverMap.putIfAbsent(observer,statefulObserver);if(previous!=null)return;mObserverMap是一个支持安全遍历的LinkedHashMap。 内部维护了Observer和其状态的键值对- 如果同一个
observer已经添加过,直接返回,不重复处理。
第三步:立即同步状态(关键!)
StatetargetState=calculateTargetState(observer);while(statefulObserver.mState.compareTo(targetState)<0){Eventevent=Event.upFrom(statefulObserver.mState);statefulObserver.dispatchEvent(lifecycleOwner,event);targetState=calculateTargetState(observer);}- 计算观察者应该达到的目标状态(
targetState),即宿主状态。 - 循环:只要观察者的当前状态落后于目标状态,就通过
Event.upFrom()获取下一个要升级的事件(例如INITIALIZED→ON_CREATE→CREATED),然后调用dispatchEvent分发出去。 - 这样,即使在
onResume后才添加观察者,它也会立即收到ON_CREATE、ON_START、ON_RESUME等缺失的事件。
注意:
Event.upFrom(state)返回从该状态到下一个状态所需的事件,比如INITIALIZED返回ON_CREATE,CREATED返回ON_START,依此类推。
第四步:触发全局同步(sync)
if(!isReentrance){sync();}isReentrance判断是否发生了重入(例如在dispatchEvent过程中又调用了addObserver)。- 如果不在重入中,则调用
sync()确保所有观察者的状态与宿主mState保持一致(主要处理那些添加过程中又发生了新的状态变化的情况)。
补充说明:为什么能防止重入?
addObserver内部用mAddingObserverCounter和mHandlingEvent两个标志位来检测重入。如果正在添加其他观察者或正在分发事件,就暂缓最后的sync(),避免死循环或重复分发。
生命周期的传递过程
大致流程
- 源头:
ComponentActivity(或 Fragment)在onCreate中注入一个没有界面的ReportFragment, 以感知Activity的生命周期。 - 捕获:
ReportFragment的生命周期方法(如onStart、onResume)会被系统调用,它拿到事件后直接转发给LifecycleRegistry。 - 分发:
LifecycleRegistry收到事件(比如ON_RESUME),会更新自己的内部状态(mState = RESUMED(表示宿主的状态)),然后遍历所有已注册的观察者,调用sync()方法:- 如果观察者状态低于当前状态 → 调用
forwardPass,逐个分发事件(如ON_RESUME) - 如果观察者状态高于当前状态(少见,如销毁过程)→ 调用
backwardPass,分发销毁事件
- 如果观察者状态低于当前状态 → 调用
- 回调:最终通过适配器(如
FullLifecycleObserverAdapter)将事件转换为具体的回调方法(如onStart()、onStop()),调用到你自定义的观察者中。
适配器的作用是把多种形态的
LifecycleObserver(注解、DefaultLifecycleObserver、FullLifecycleObserver等)统一成LifecycleEventObserver这一种接口,让LifecycleRegistry可以用标准、简单的方式分发事件,而不用关心观察者具体是怎么实现的。
一句话总结:Activity 通过一个隐藏 Fragment 感知生命周期,交给
LifecycleRegistry做状态机管理,再由它同步给所有观察者。
四、关键实现细节
1. Activity 如何感知生命周期?
- API ≥ 29:通过
Activity.registerActivityLifecycleCallbacks直接注册回调。 - API < 29:往 Activity 中添加一个无界面的
ReportFragment,它的生命周期回调会同步转发给LifecycleRegistry。
2. 添加观察者时(addObserver)做了什么?
- 将观察者包装成
ObserverWithState(内部持有当前状态)。 - 存入
mObserverMap(自定义安全可遍历 Map)。 - 立即同步:如果宿主已经有生命周期状态(例如在
onResume之后才添加),会立即forwardPass将缺失的事件(ON_CREATE、ON_START、ON_RESUME)按顺序分发给新观察者。
3. 状态同步核心(sync())
- 比较
mState(宿主当前状态)与mObserverMap中最老/最新观察者的状态。 - 向前同步(
forwardPass):观察者状态落后 → 逐步发出Event.upFrom(state)直到追上mState。 - 向后同步(
backwardPass):观察者状态超前(极少场景,如 Fragment 嵌套)→ 发出回退事件。
4. 事件如何到达自定义 Observer?
- 观察者可能实现
DefaultLifecycleObserver、LifecycleEventObserver或使用注解。 Lifecycling.lifecycleEventObserver()根据类型返回适配器:FullLifecycleObserverAdapter:将Event转为具体onCreate/onStart/...回调。- 注解方式:通过注解处理器生成适配代码。
- 最终调用
mLifecycleObserver.onStateChanged(owner, event),再转发到业务方法(如onStart())。
五、面试官可能追问的问题
Q1:为什么LifecycleObserver是空接口?
为了支持多种监听方式:注解(
@OnLifecycleEvent)和接口实现(DefaultLifecycleObserver)。空接口作为标记,具体回调通过适配器转换。
Q2:LifecycleRegistry如何保证线程安全?
内部通过
enforceMainThreadIfNeeded强制主线程操作,避免并发问题。早期版本有锁和重入标记,现在直接要求主线程。
Q3:如果在onResume之后添加观察者,它会错过onCreate事件吗?
不会。
addObserver会立即计算目标状态,并通过forwardPass把缺失的事件按顺序补发。
Q4:Lifecycle如何处理内存泄漏?
LifecycleRegistry中持有LifecycleOwner时使用WeakReference,并且onDestroy事件后会停止分发。
Q5:ReportFragment为什么还在用(API 29 以上不是有回调吗)?
为了向下兼容。API 29+ 用
LifecycleCallbacks,低版本用无界面的 Fragment,保证所有 Android 版本都能捕获生命周期。
六、总结
Lifecycle 通过
LifecycleOwner(Activity/Fragment)利用ReportFragment或系统回调捕获生命周期事件,交给LifecycleRegistry维护状态机,再通过适配器模式将事件分发给注册的LifecycleObserver,实现生命周期感知。
深入理解 Jetpack Lifecycle(原理篇)你好,我是朱涛。最近我打算系统化梳理下 Android Jetpa - 掘金
