Android Jetpack
组件是库的集合,这些库是为协同工作而构建的,不过也可以单独采用,同时利用Kotlin
语言功能帮助您提高工作效率。可全部使用,也可混合搭配!
1.什么是 Lifecycle
?:它是可以感知 Activity
、 Fragment
的生命周期,并将变化通知到已注册的观察者。让代码符合生命周期规范,有效的避免了内存泄漏等问题。
2.基本使用:被动的通知 View
层生命周期变化让逻辑层拥有 LifecycleOwner
对象,因为view层实现了 LifecycleOwner
接口,所以可以在view层初始化的时候,直接赋值,有了 LifecycleOwner
对象,就可以通过 getLifecycle
方法获取到 Lifecycle
对象了(附图片)。
-
Lifecycle
有4个比较重要的类:LifecycleOwner
,LifecycleObserver
、Lifecycle
和LifecycleRegistry
。
3.1 LifecycleOwner
,它是一个接口,我们现在用的 Androidx
包下的 AppcompatActivty
和 Fragment
都默认实现了 LifecycleOwner
这个接口,这个接口提供了 getLifecycle()
方法来获取其 Lifecycle
对象。
也就是上面说的直接在 Activity
添加 addObserver(new CustomObserver())
就能感知 Activity
生命周期了。
3.2 LifecycleObserver
,它是一个空的接口,这个接口只是来标志这个是对Lifecycle
的观察者,内部没有任何方法,全部都依赖于OnLifecycleEvent
注解
3.3 Lifecycle
,它是一个抽象的类,定义了2个枚举类Event
和State
,addObserver
和removeObserver
方法。
3.4 LifecycleRegistry
:它是 Lifecycle
的唯一实现类。主要用来注册观察者( LifecycleObserver
),以及分发宿主状态给它们(可以处理多个观察者)
上面简单看了下四个类的源码。真正的源码如下所示
在看源码之前,,我们可能产生几个疑问
- Lifecycle是怎样感知生命周期的?
- Lifecycle是如何处理生命周期的?
- LifecycleObserver的方法是怎么回调的呢?
- 为什么LifecycleObserver可以感知到Activity的生命周期?
源码解析(以LifeCycleActivity.class为例):
上图中1标注的我们拆分成2步:
getLifecycle()
和addObserver()
①先看
getLifecycle()
:它是ComponentActivity
里面的mLifecycleRegistry
是 LifecycleRegistry
对象,LifecycleRegistry
是 LifeCycle
的子类;
②addObserver()
上面代码可看出,
addObserver()
干了以下几件事:1、可以添加多个观察者,这时候需要维护他们的状态,每次添加新的观察者的初始状态是
INITIALIZED
;2、然后把
LifecycleObserver
包装成ObserverWithState
;3、把
Observer
添加到map
集合中。观察者已经添加完成了,那么如何将生命周期的变化通知观察者呢?
再会到
ComponentActivity
中,仔细看下ComponentActivity
的onCreate()
方法有一个ReportFragment.injectIfNeededIn(this)
;它初始化了一个
ReportFragment
,仔细看下ReportFragment
源码可知,它是向Activity
添加了一个没有页面的Fragment
,并且ReportFragment
中的各个生命周期都调用了dispatch(Lifecycle.Event event)
方法,它里面的参数就是传递了不同的
Event
值,再仔细看dispatch
里面干了2件事:(1)如果
Activity
实现了LifecycleRegistryOwner
接口的话,就调用LifecycleRegistryOwner
的handleLifecycleEvent
的方法;(2)如果
Activity
实现了LifecycleOwner
接口的话,就调用LifecycleRegistry
的handleLifecycleEvent
的方法;经过我们上面的介绍,
Activity
是实现了LifecycleOwner
的接口,所以会执行LifecycleRegistry
的handleLifecycleEvent
的方法。
看到这里我们可以回答第4中的前2个问题了。
接下来看下handleLifecycleEvent方法
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
1.首先根据需要分发的事件,获取宿主当前处于什么状态
假设分发的是 ON_START
事件,那么根据 getStateAfter()
方法我们可以知道,宿主当前是处于STARTED
状态。
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;
}
2.根据第一步获取的宿主状态设置当前的状态并通知观察者
private void moveToState(State next) {
if (mState == next) {
return;
}
//设置当前状态
mState = next;
...
//通知观察者
sync();
}
下面来看一下 sync
方法:
private void sync() {
while (!isSynced()) {
//如果宿主当前的状态 小于 mObserverMap 集合中最先添加的那个观察者的状态
//则说明宿主可能发生了状态回退,比如当前是 RESUMED 状态,执行了onPause 则回退到STARTED 状态
//此时调用 backwardPass 给集合中的每个一观察者分发一个 on_pause 事件,并同步它的状态。
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
//如果宿主当前状态 大于 mObserverMap 集合中最先添加的那个观察者的状态
//则说明宿主可能发生了状态前进,比如当前是 STARTED 状态,执行了onResume 则前进到RESUMED 状态
//此时调用 forwardPass 给集合中的每个一观察者分发一个 on_resume 事件,并同步它的状态。
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
ObserverWithState
源码分析
ObserverWithState
是LifecycleRegistry
中持有观察者及其状态的内部类。
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
//把传入的 LifecycleObserver 适配成 LifecycleEventObserver,目的是为了统一事件的分发形式。
//在之前的文章里介绍过实现观察者有三种形式,每一种接收的事件类型都不一样,如果在分发的时候不统一事件分发的形式,将会变得很麻烦
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
//执行事件分发
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
至此LifeCycle源码讲解完成,希望能大家有帮助,谢谢