1. 概述
Lifecycle-aware 组件是Jetpack 的重要组成部分,它不仅提供给我们单独使用,同时也是其他两个组件 ViewModel 和 LiveData 的基础,具体使用请参看官方文档Handling Lifecycles with Lifecycle-Aware Components
。本文旨在分析Lifecycle组件的核心类LifecycleRegistry.java。
在Lifecycle未出现之前,要处理生命周期相关的问题,你需要 Activity 中使用过各种 xxxManager.start()、xxxManager.stop(),或者封装过 Android 生命周期对应的接口并给予实现,当然也可以使用优秀的第三方框架,例如RxLifecycle。Google 为降低开发难度,推出 Jetpack并顺便解决了这个问题。
从各种实现方式中,Lifecycle 选择了观察者模式+注解,方便将业务逻辑从 Activity 中抽离出来,通过注解处理自己关心的状态。
2. 实现思路
我们知道生命周期回调在 Activity 中实现,onCreate->...->onDestroy。要达到控制观察者生命周期的目的,Lifecycle 大致结构如下:
- 提供一个管理所有 Observer 的类,用于添加、移除、状态流转、分发事件等功能
- Activity 需要持有这个管理类来与自身的生命周期产生关联
作为一个开源框架,这个管理类需要考虑到各种情况,使用者可能在任何时候添加、移除 Observer,包括在事件分发的时候递归使用。Lifecycle 中承担这个职责的是 LifecycleRegistry,下面开始分析。(关于整个框架的组织结构可以阅读末尾的参考文章)
3. LifecycleRegistry
3.1 构造器
LifecycleRegistry 的生命周期跟随宿主 Activity ,如果宿主被销毁,那么事件也不必分发;同时 LifecycleRegistry 也需要记录当前的 state 来决定分发什么事件
// 1. LifecycleRegistry对应的 state,一般而言跟随 Activity
private State mState;
// 2. 弱引用,避免泄露
private final WeakReference<LifecycleOwner> mLifecycleOwner;
public LifecycleRegistry(@NonNull LifecycleOwner provider) {
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
}
3.2 State 和 Event
首先看一下官方提供的一张示意图
组件将 State、Event 定义在 LifecycleRegistry 的父类 Lifecycle.java中
// ON_CREATE < ON_START < ON_RESUME < ON_PAUSE < ON_STOP < ON_DESTROY < ON_ANY
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
// DESTROYED < INITIALIZED < CREATED < STARTED < RESUMED
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
State 流转分为两个方向,姑且将 app 启动(onCreate->...->onResume)定义为正向流转, app 关闭(onResume->...->onDestroy)定义为逆向流程。
3.3 添加 Observer
1.赋予Observer状态
// 除非在 onDestroy 方法中调用添加,否则将新的Observer标记为初始状态 INITIALIZED
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
2.解析Observer
// Observer装饰类,主要维护Observer对应的state以及解析Observer中被注解的方法,以便事件分发时得到调用。
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
3.避免重复添加,这里可以看到LifecycleRegistry维护了一个Observer列表
// 用于判断是否重复订阅
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
4.判断宿主是否被销毁
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
5.判断是否递归调用
// 1. 判断是否是重入,即下面序号8处中,Observer可能会调用 addObserver方法或者moveToState方法
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
- 计算一个最小的
State,比较对象有前一个观察者的state、LifecycleRegistry#mState以及mParentStates.get(mParentStates.size() - 1)。mParentStates先不用管后面再讲
State targetState = calculateTargetState(observer);
- 标记正在添加
Observer
//自加,表明正在执行一个添加 Observer 的操作
mAddingObserverCounter++;
- 如果正在添加的
Observer的state(一般是INITIALIZED)小于序号6计算出的targetState,将Observer流转至targetState,每次流转会分发对应的事件。
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);// 先不管,后面再讲
// 分发事件
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();// 先不管,后面再讲
targetState = calculateTargetState(observer);
}
- 当满足条件时,对整个
Observer列表执行state同步。
// 这里的判定条件让我想了很久,现举个栗子说明一下
// 现在假设正在添加观察者 A
// 1. 初始状态下,isReentrance==false
// 2. 执行到序号7 mAddingObserverCounter++ 后,进入序号8的 while 循环
// 3. while循环中会分发事件,A接收到这个事件时,可以进行添加观察者 B 的操作,实现递归,再次进入这个方法。
// 4. 此时条件满足,isReentrance == true,那么在这一个层级调用中,因不满足条件,sync方法不会得到调用。
// 结语:这里分析了mAddingObserverCounter变化对isReentrance的影响,同理,事件分发中执行moveToState方法,会引起mHandlingEvent的变化。同样影响 sync 的调用。
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
小结:
- 结合6、8分析,
Observer队列中,队首比队尾的state的值大,这在源码注释是有做说明的。/** * Custom list that keeps observers and can handle removals / additions during traversal. * * Invariant: at any moment of time for observer1 & observer2: * if addition_order(observer1) < addition_order(observer2), then * state(observer1) >= state(observer2), */ private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>(); - 结合5、7、8、9分析,如果事件分发中不存在
Observer干扰LifecycleRegistry的行为,sync会很快得到调用;否则要等到这些干扰结束后才在最外层调用中执行sync,大家可以画个表格分析addObserver和moveState方法在内部相互调用的各种情况。
3.4 sync方法
10.判断宿主是否被销毁
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
- 如果满足条件,则执行同步操作
// 判断是否已同步的标准是:队首和队尾的所标记的的state相同,并且和LifecycleRegistry#mState相同。
while (!isSynced()) {
// 1. mNewEventOccurred控制着是否能够进入 sync 方法和控制 sync 内部是否分发事件。如果出现递归调用,mNewEventOccurred==true,上述两种行为都不会执行,直到返回递归栈顶层。
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
- moveToState(),存在干扰行为时,中途返回,不会调用
sync
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
- 即逆向流转,
onResume->...->onDestroy
private void backwardPass(LifecycleOwner lifecycleOwner) {
//逆序排列,最后添加的Observer最靠前,根据前文的分析,队尾的 state 值最小。
Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
mObserverMap.descendingIterator();
// 即序号11中分析的,如果事件分发中存在递归调用 moveToState 方法,!mNewEventOccurred==false,跳出循环
while (descendingIterator.hasNext() && !mNewEventOccurred) {
// 外层遍历所有 Observer
Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
ObserverWithState observer = entry.getValue();
// 内层流传所有的 State
while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
Event event = downEvent(observer.mState);
pushParentState(getStateAfter(event));// 后面再讲
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
3.5 mParentStates
对于mParentStates,同样是百思不得其解,虽然给了文档说明,但还是太绕了,我们一起看一看。
// we have to keep it for cases:
// void onStart() {
// mRegistry.removeObserver(this);
// mRegistry.add(newObserver);
// }
// newObserver should be brought only to CREATED state during the execution of
// this onStart method. our invariant with mObserverMap doesn't help, because parent observer
// is no longer in the map.
private ArrayList<State> mParentStates = new ArrayList<>();
文档中举了一个例子,说明为什么要引入mParentStates,这里就不去翻译它了,太抽象,我们按照它这个例子走一遍看看有什么样的效果。
分析,大家结合官方示意图和 addObserver 方法的源码会更直观
- 执行上面
onStart方法前,mRegistry#mState==STARTED,mHandlingEvent = trueprivate void moveToState(State next) { if (mState == next) { return; } mState = next; .. mHandlingEvent = true; sync(); mHandlingEvent = false; } - 在所有的事件分发代码两侧都会保存和移除 state 操作,这里保存了观察者 A 流转之前的
State==CREATED。pushParentState(observer.mState); observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState)); popParentState(); - A在 onStart 移除自己,不会触发任何回调
- 向LifecycleRegistry添加新的 Observer B,执行 addObserver 方法,B 被置为 INITIALIZED,在执行calculateTargetState方法时,比较对象是(1)前一个观察者的state(2)mRegistry#mState==STARTED、(3)mParentStates记录的state==CREATED,最小值是(3)。
- 接着执行后面while循环体,B的
state从INITIALIZED流转到CREATED,分发ON_CREATE事件。 mHandlingEvent == true;不满足执行sync方法的条件。
结论:如果不利用mParentStates记录记录
state,那么第4步得到的就是(2)mRegistry#mState==STARTED,结果就是第5步还会多分发一个ON_START事件。结合源码的注释说明就能理解了,「newObserver should be brought only to CREATED state during the execution of this onStart method」
参考:
Android官方架构组件Lifecycle:生命周期组件详解&原理分析
Android-Lifecycle超能解析-生命周期的那些事儿
Android Architecture Components(一)Lifecycle源码分析