在 Android 中,我们可以使用 Jetpack
的 Lifecycle
组件来管理我们的生命周期,可以执行操作来响应另一个组件(例如 Activity
)的生命周期变化。利用 Lifecycle
,我们可以写出非常精简和容易维护的代码。
关于 Lifecycle
的基础知识,再次不做重复描述,不了解的朋友可以直接参考官方文档:Lifecycle 。
我们关注一下如何实现自定义的 LifecycleOwner
:
LifecycleRegistry
lifecycleRegistry = LifecycleRegistry(this) 复制代码
lifecycleRegistry.markState(Lifecycle.State.CREATED) 复制代码
我们自己来实现一个 LifecyclerOwner
,假设一个场景,我们有非常复杂的UI布局,某些UI控件我们希望能动态的插拔在布局上,并且在拔下这个控件或者页面退出的时候,这个控件里面的资源可以自动释放。
我们先自定义我们需要动态插板的 View
:
我们提供了一个 release
方法,代表生命周期走到 destroy 的时候,执行一些释放逻辑。
class StubView : LinearLayout { fun release() { Log.d("StubView", "release") } init { val tv = TextView(context).apply { text= "占位控件" gravity = Gravity.CENTER setBackgroundColor(Color.BLUE) setTextColor(Color.WHITE) } this.addView(tv) } } 复制代码
既然我们需要 View
有自己的生命周期监听,那么我们需要自定义一个 LifecycleOwner
:
class LifecycleOwnerWrapper(owner: LifecycleOwner) : LifecycleOwner { private var lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(owner) override fun getLifecycle(): Lifecycle { return lifecycleRegistry } fun markState(state: Lifecycle.State) { lifecycleRegistry.currentState = state } fun addObserver(ob: LifecycleObserver) { lifecycleRegistry.addObserver(ob) } } 复制代码
接着我们定义一个 ViewHolder
来表示ui 插拔的逻辑, install
和 uninstall
方法分别代表装载和卸载这个控件:
class StubViewHolder(val owner: Fragment, val binding: FragmentJetpackLifecycleBinding) { private var lifecycleOwner : LifecycleOwner = LifecycleOwnerWrapper(owner) fun addLifecycleObserver(ob: LifecycleObserver) { (lifecycleOwner as LifecycleOwnerWrapper).addObserver(ob) } fun install() { val stub = StubView(owner.context) (lifecycleOwner as LifecycleOwnerWrapper).markState(Lifecycle.State.STARTED) binding.stubContainer.addView(stub) } fun unInstall() { for (index in 0 until binding.stubContainer.childCount) { val child = binding.stubContainer[index] if (child is StubView) { (lifecycleOwner as LifecycleOwnerWrapper).markState(Lifecycle.State.DESTROYED) binding.stubContainer.removeView(child) } } } } 复制代码
在卸载的时候,把 LifecycleIwberWrapper
的状态标记成了 DESTROYED
, 这时候我们在 Fragment
里面就可以绑定 Observer
去监听生命周期的变化:
val stubVH = StubViewHolder(this, binding).apply { addLifecycleObserver(lifecycleOb) } lifecycle.addObserver(lifecycleOb) // 拔掉 stubVH.unInstall() // 插入 stubVH.install() 复制代码
然后定义我们的 LifecycleOb
,当生命周期的事件是 Event.ON_DESTROY
的时候,就会从容器里面找到这个 StubView
,然后在它被 remove 之前,执行它的 release
方法。
val lifecycleOb = LifecycleEventObserver { source, event -> when (event) { Lifecycle.Event.ON_DESTROY -> { // 销毁逻辑 for (index in 0 until binding.stubContainer.childCount) { val child = binding.stubContainer[index] if (child is StubView) { child.release() } } } } } 复制代码
到这里,我们就完成了一个自定义 LifecycleOwner
的例子,那么 Jetpack
是怎么实现 Lifecycle
的这一套逻辑的呢?我们从实现可以一探究竟
我们来看下关键的 LifecycleRegistry
对象:
mObserverMap
FastSafeIterableMap<LifecycleObserver, ObserverWithState>
这是一个类似 LinekHashMap
的 map 对象,存储了我们添加的 LifecycleObserver
及状态,支持在迭代过程中对 map 进行修改。并且记录了 mStart
和 mEnd
mAddingObserverCounter && mHandlingEvent
这两变量的作用基本一致,区分当前是否正在添加 Observer
或者处理生命周期事件。
moveToState
修改当前的状态
sync
状态不是已经同步的话,就一直执行while循环里面的逻辑去调整状态。如果当前状态小于最旧的observer的状态,那么状态是需要向后转换的,也就是backwardPass
,如果当前状态大于最新的observer的状态,那么状态是需要向后转换的,也就是 forwardPass
。
例如 backwardPass
dispatchEvent
方法。这样就可以同步所有 Observer 的当前生命周期状态:
void dispatchEvent(LifecycleOwner owner, Event event) { State newState = getStateAfter(event); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; } 复制代码
大致的流程和结构如下图:
我们直接看 LifecycleRegistry
的 addObserver
:
@Override public void addObserver(@NonNull LifecycleObserver observer) { State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED; ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver); LifecycleOwner lifecycleOwner = mLifecycleOwner.get(); boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent; // 判断是否是重入 State targetState = calculateTargetState(observer); mAddingObserverCounter++; while ((statefulObserver.mState.compareTo(targetState) < 0 && mObserverMap.contains(observer))) { pushParentState(statefulObserver.mState); statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState)); popParentState(); targetState = calculateTargetState(observer); } if (!isReentrance) { sync(); } mAddingObserverCounter--; } 复制代码
在添加生命周期监听的时候,首先会把 Observer
对象添加到 map
里面去。且生命周期是 INITIALIZED。
所以这时候需要调用 calculateTargetState
来计算正确的 state,并且 dispatch 下去。
isReentrance
则是用来判断是否是重入的,例如在 Observer
的回调里面又调用了 addObserver
,那么就是重入的了。只有在非重入的情况下,我们才需要进行同步的逻辑。 否则就成了递归调用,没有必要。反正其他生命周期的操作也会对所有的 LifecycleObserver
进行同步。
那么 sync
的时候到生命周期按照什么规则同步呢?在 forwardPass
和 backwardPass
里面,我们能看到 upEvent
和 downEvent
的调用:
upEvent:
private static Event upEvent(State state) { switch (state) { case INITIALIZED: case DESTROYED: return ON_CREATE; case CREATED: return ON_START; case STARTED: return ON_RESUME; case RESUMED: throw new IllegalArgumentException(); } throw new IllegalArgumentException("Unexpected state value " + state); } 复制代码
downEvent: _
private static Event downEvent(State state) { switch (state) { case INITIALIZED: throw new IllegalArgumentException(); case CREATED: return ON_DESTROY; case STARTED: return ON_STOP; case RESUMED: return ON_PAUSE; case DESTROYED: throw new IllegalArgumentException(); } throw new IllegalArgumentException("Unexpected state value " + state); } 复制代码
而最终的状态也会根据 getStateAfter
来得到:
getStateAfter: _
static State getStateAfter(Event event) { switch (event) { case ON_CREATE: case ON_STOP: return CREATED; case ON_START: case ON_PAUSE: return STARTED; case ON_RESUME: return RESUMED; case ON_DESTROY: return DESTROYED; case ON_ANY: break; } throw new IllegalArgumentException("Unexpected event value " + event); } 复制代码
这里非常的绕,直接读容易绕晕,我们整理一下:
downEvent
upEvent
getStateAfter
仔细看会发现这个其实就对应官网的那张 Lifecycle
的生命周期图:
在更改状态的时候,会调用 moveToState
方法:
private void moveToState(State next) { mState = next; mHandlingEvent = true; sync(); mHandlingEvent = false; } 复制代码
这里仍然会在修改后同步状态。在 forward 和 backward 里都会调用
observer.dispatchEvent(lifecycleOwner, event); 复制代码
void dispatchEvent(LifecycleOwner owner, Event event) { State newState = getStateAfter(event); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; } 复制代码
这里就会回调我们的 LifecycleEventObserver
的 onStateChanged
方法。
Lifecycle
本身大大简化了生命周期相关的处理,非常有助于代码解耦。在 Jetpack
套件里面,其实也非常多的用到了 Lifecycle
。感兴趣的朋友也可以分享一下。
另外也欢迎大家关注我的公众号: 半行代码
: