看到这里应该能feel到为什么需要 可重入 的标记了,如果没有的话,可能产生sync()嵌套:
moveToState(state1) → sync() → moveToState(state1) → sync() addObserver() → addObserver() → sync() → sync() addObserver() → moveToState() → sync() → sync()
最后都会走 最外层(顶层)的sync(),中间发生的sync() 完全没必要执行,减少不必要的迭代或错误,通过这三个字段配合来完成:mHandlingEvent、mNewEventOccurred、mAddingObserverCounter。
然后还有个属性还没弄清楚是干嘛的:
解释下:它为了解决 事件嵌套 中 增加新观察者对观察者队列有序性的破坏。怎么说,看代码:
假如没有mParentStates,好像还正常,然后注释给了一个反例:
- Observer1 在 onStart() 回调中把自己从集合中移除,然后添加了新的Observer2;
- 假如集合中只有Observer1这个观察者,移除后集合就是空的,会导致Observer2直接更新到LifecycleRegister的STARTED状态;
- 但,此时Observer1的 onStart() 回调还未执行完,而 Observer2 的 ON_START就回调执行完了,显然就违背了LifecycleRegistry的设计 → 观察者的同步是按照顺序执行的;
添加了这个属性,在执行观察者回调前 pushParentState()
暂存当前观察者,回调完后 popParentState()
移除观察者,然后执行 calculateTargetState() 时判断是否为空,不为空取出最后一个缓存的观察者,然后取:LifecycleRegister当前状态、
previous当前状态、缓存观察者状态中的最小值,作为当前观察者的状态。
关于 LifecycleRegistry 关键代码的的解析就这些,它还对外暴露了几个改变状态的方法:
Activiyt和Fragment中就有用到,等下会碰到,先继续往下走~
② ReportFragment类
一个专门用于分发生命周期事件的无UI界面的Fragment,入口方法 injectIfNeededIn()
很清晰明了,API版本大于等于29,直接使用 activity.registerActivityLifecycleCallbacks()
,重写生命周期回调方法进行事件分发:
API版本小于29,直接开启一个事务,新建一个ReportFragment实例,添加到activity上,在ReportFragment中已对生命周期回调方法进行了重写,完成事件分发:
然后 dispatch() 就是调下 LifecycleRegistry.handleLifecycleEvent()
而已。
还定义了一个 ActivityInitializationListener
接口:
支持外部通过 setProcessListener()
传入自定义实现,在 lifecycle-process 源码中看到过:
留了个后门,让ProcessLifecycleOwner的onStart()和onResume(),先于第一个Activity执行。
③ ViewTreeLifecycleOwner类
看着有点蒙?看下 set() 调用处的代码就知道了:
ComponentActivity实现了LifecycleOwner接口,所以这里传入了 根视图 + ComponentActivity这个LifecycleOwner
而在调用 get() 传入view时,通过getParent()一层层往上拿,直到获取到这个LifecycleOwner为止(也可能没有返回空)。
那这有什么用呢?简化代码!
View内部需要基于lifecycle进行某些操作时,可以避免Lifecycle的层层传递,比如LiveData订阅。
0x4、Activity中的Lifecycle相关
实现了Lifecycle接口,没干啥活,毕竟生命周期事件分发的活都交给ReportFragment了,直接贴相关代码~
// 定义一个LifecycleRegistry private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { ... ReportFragment.injectIfNeededIn(this); // 使用Report分发生命周期事件 ... } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { Lifecycle lifecycle = getLifecycle(); if (lifecycle instanceof LifecycleRegistry) { // 设置mLifecycleRegistry当前状态为CREATED ((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED); } ... } @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; }
0x5、Fragment中的Lifecycle相关
同样实现了LifecycleOwner接口,实例化了一个LifecycleRegistry用于生命周期事件转发。
有一点要注意,在大多数情况下Fragment与其管理的View(视图)的生命周期是一致的,但存在特例:
Fragment被replace()时 → FragmentTransaction.detach() → 回调onDestroyView()销毁视图 → 不走onDestory() → 使得Fragment状态得以保留,当前内存空间得以释放,下次加载直接onCreateView(),速度更快。
这样的操作也导致了Fragment的生命周期比View长,所以Fragment还定义了一个 FragmentViewLifecycleOwner
来单独处理View的生命周期,官方文档有给出 《Fragment lifecycle》 给出了这样一张图:
源码注释中也有给出Fragment中管理的View:生命周期与Fragment自身回调间的对应关系。
直接抠出来,方便看:
- onViewStateRestored()后 → ON_CREATE
- onStart()后 → ON_START
- onResume()后 → ON_RESUME
- onPause()前 → ON_PAUSE
- onStop()前 → ON_STOP
- onDestroyView()前 → ON_DESTROY
可调用 getViewLifecycleOwner
() 获得View的LifecycleOwner哈~
Fragment中涉及到状态流转的核心代码如下:
void performCreate(Bundle savedInstanceState) { if (Build.VERSION.SDK_INT >= 19) { mLifecycleRegistry.addObserver(new LifecycleEventObserver() { @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (event == Lifecycle.Event.ON_STOP) { if (mView != null) { mView.cancelPendingInputEvents(); } } } }); } mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); } void performStart() { mState = STARTED; mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); if (mView != null) { mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START); } } void performResume() { mState = RESUMED; mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME); if (mView != null) { mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME); } } void performPause() { if (mView != null) { mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE); } mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE); mState = AWAITING_ENTER_EFFECTS; } void performStop() { if (mView != null) { mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP); } mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); mState = ACTIVITY_CREATED; } void performDestroy() { mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY); mState = ATTACHED; }
既有Fragment Lifecycle的State,又有ViewLifecycleOwner的State,还有Fragment自身的State,这个要区分哈:
另外,相比以前的源码,Fragment发生了较大的改动,比如状态管理相关的剥离到 FragmentStateManager
中了,笔者目前还不太了解,就不先不往下挖了,后续专门研究Fragment再说吧~
0x6、小结
关于源码的解析暂且到这里吧,Lifecycle的路数基本摸清了,小结下要点方便回顾:
- ① Lifecycle的核心思想是:模板模式 + 观察者模式;
- ② Lifecycle抽象类:抽象被观察者,定义了两个生命周期相关的枚举 Event 和 State,统一了State升降级对应触发的Event(关联关系),提供了添加、移除观察者,获取当前State的三个抽象方法;
- ③ LifecycleObserver:空接口,类型标记,抽象观察者;
- ④ FullLifecycleObserver、LifecycleEventObserver:继承LifecycleObserver接口,提供两种不同的回调方式;
- ⑤ DefaultLifecycleObserver:继承FullLifecycleObserver,利用Java 8特性【接口声明默认方法】,默认重写了回调方法,具体观察者;
- ⑥ LifecycleOwner:提供一个获取Lifecycle的方法;
- ⑦ Lifecycling → 对传入LifecycleOwner进行统一的类型包装,使得Event分发过程得以统一入口;
- ⑧ LifecycleRegistry → 具体观察者,组件状态维护,使用自定义支持迭代时增删元素的 FastSafeIterableMap (HashMap套链表) 保存观察者。键为LifecycleObserver,值为 ObserverWithState,其中包含观察者与状态关联,并提供事件分发方法dispatchEvent();
- ⑨ 通过三个变量:mHandlingEvent、mNewEventOccurred、mAddingObserverCounter 的配合来解决 事件嵌套 引起的sync()多次执行;
- ⑩ 额外定义了一个 mParentStates 来解决 事件嵌套 中 增加新观察者对观察者队列有序性的破坏。
以上就是本节的全部内容,后续肝多几个组件,再来个实战篇吧,谢谢~
Tips:关于Lifecycle库的改动可以参见:Lifecycle,其他库亦是如此~
参考文献:
- 官方文档:使用生命周期感知型组件处理生命周期
- 官方文档:Fragment lifecycle
- 重学安卓:为你还原一个真实的 Jetpack Lifecycle
- Lifecycle之SafeIterableMap
- 带你理解Jetpack——Lifecycle篇
- 【Android】使用ViewTreeLifecycleOwner获取Lifecycle
- “终于懂了“系列:Jetpack AAC完整解析(一)Lifecycle 完全掌握!
- 从源码看 Jetpack(1)- Lifecycle 源码详解