Jetpack Lifecycle记录
在 Android 中,我们可以使用 Jetpack
的 Lifecycle
组件来管理我们的生命周期,可以执行操作来响应另一个组件(例如 Activity
)的生命周期变化。利用 Lifecycle
,我们可以写出非常精简和容易维护的代码。
关于 Lifecycle
的基础知识,再次不做重复描述,不了解的朋友可以直接参考官方文档:Lifecycle 。
我们关注一下如何实现自定义的 LifecycleOwner
:
实现自己的 LifecycleRegistry
lifecycleRegistry = LifecycleRegistry(this)
修改到自己的生命周期状态
代码语言:javascript复制lifecycleRegistry.markState(Lifecycle.State.CREATED)
自己实现一个 LifecycleOwner
我们自己来实现一个 LifecyclerOwner
,假设一个场景,我们有非常复杂的UI布局,某些UI控件我们希望能动态的插拔在布局上,并且在拔下这个控件或者页面退出的时候,这个控件里面的资源可以自动释放。
image.png
我们先自定义我们需要动态插板的 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
这个每个状态比当前状态小的 observer 都会执行 dispatchEvent
方法。这样就可以同步所有 Observer 的当前生命周期状态:
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
绑定Observer 过程
大致的流程和结构如下图:
我们直接看 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:
代码语言:javascript复制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: _
代码语言:javascript复制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: _
代码语言:javascript复制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
- INITIALIZED -> 无
- CREATED -> ON_DESTROY
- STARTED -> ON_STOP
- RESUMED -> ON_PAUSE
- DESTROYED -> 无
upEvent
- INITIALIZED -> ON_CREATE
- DESTROYED -> ON_CREATE
- CREATED -> ON_START
- STARTED -> ON_RESUME
- RESUMED -> 无
getStateAfter
- ON_CREATE、ON_STOP -> CREATED
- ON_START、ON_PAUSE -> STARTED
- ON_RESUME -> RESUMED
- ON_DESTROY -> DESTROYED
仔细看会发现这个其实就对应官网的那张 Lifecycle
的生命周期图:
image.png
回调
在更改状态的时候,会调用 moveToState
方法:
private void moveToState(State next) {
mState = next;
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
这里仍然会在修改后同步状态。在 forward 和 backward 里都会调用
代码语言:javascript复制observer.dispatchEvent(lifecycleOwner, event);
代码语言:javascript复制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
。感兴趣的朋友也可以分享一下。