Androd架构组件Lifecycle源码分析

本文主要从源码角度介绍架构组件Lifecycle的实现原理,默认读者已经熟悉Lifecycle的基本使用。

功能与使用场景

功能

外部使用者可以通过Lifecycle来订阅Activity与Fragment的生命周期变化,同时也可以主动去获取当前Activity与Fragment处于哪个生命周期。

使用场景

在实现MVP与MVVM模式的时候,Presenter与ViewModel有时候会有初始化或者回收的逻辑,而这两部分的逻辑一般是与其宿主,也就是Activity或Fragment的生命周期强相关的。这个时候就可以借助Lifecycle赋予Presenter等实例感知宿主生命周期的能力,以更优雅的方式完成需求。

除此之外,有一些自定义View可能也有感知生命周期的需求,同样的也可以借助Lifecycle去实现。

整体架构图

整体的设计采用了订阅者模式以及状态机模式,类结构图如下:

image-20181014144223737

简单介绍下比较重要的几个类:

  • LifecycleObserver接口:顾名思义,实现了该接口的对象就可以感知到LifecycleOwner的生命周期。
  • LifecycleOwner接口:实现了该接口的对象就有了生命周期,是一个可被观察的对象,通过持有LifecycleRegistry来实现生命周期变化的功能。
  • Lifecycle、LifecycleRegistry:前者提供生命周期相关的对外接口,后者是前者的具体实现,提供声明周期变化等的具体实现。
  • State、Event:代表状态与生命周期事件的枚举类。

源码分析

下面的源码分析均从Activity相关的实现入手,Fragment相关的实现类似,不再赘述。按照惯例从问题出发,如下:

订阅者如何注册与管理?

首先明确一个局部的持有关系,Activity与LifecycleRegistry是一对一的关系,其对外的生命周期相关功能都是由LifecycleRegistry实现的。自然,注册功能也是如此。先看下注册入口,LifecycleRegistry.addObserver():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class LifecycleRegistry extends Lifecycle {
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();

// 核心逻辑是添加订阅者到mObserverMap,并向它发送之前它没收到的生命周期事件
public void addObserver(@NonNull LifecycleObserver observer) {
// 订阅者也会记录生命周期,默认从INITIALIZED开始
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
// 省略一些代码
// 如果订阅者订阅的时候,被订阅者的生命周期大于INITIALIZED,
// 则被订阅者会发送之前所有的生命周期变化通知给订阅者
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
// 分发生命周期,并提升订阅者记录的生命周期信息
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
}
}

可以看到主要的逻辑就是添加订阅者并发送之前没有发送的生命周期事件。

LifecycleRegistry如何实现状态变更?

首先需要明确的是,状态的管理并不在LifecycleOwner,而是在被它持有的LifecycleRegistry。LifecycleOwner通过handleLifecycleEvent()通知LifecycleRegistry进行状态变更。具体看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public class LifecycleRegistry extends Lifecycle {
private State mState;

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
// 获取下一个生命周期状态
State next = getStateAfter(event);
// 变化到下一个生命周期
moveToState(next);
}

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;
}

private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
while (!isSynced()) {
mNewEventOccurred = false;
// 根据状态差值做状态偏移
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;
}

private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
// 通知状态的变更
observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
popParentState();
}
}
}

private void backwardPass(LifecycleOwner lifecycleOwner) {
// 逻辑与forwardPass()类似
}

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);
}

private static Event upEvent(State state) {
// 逻辑与downEvent()类似
}
}
如何将状态变更通知到订阅者?

以SupportActivity为例,它是一个LifecycleOwner,持有了LifecycleRegistry,但它并没有在自己的生命周期函数中调用LifecycleRegistry的分发方法来分发生命周期变化事件,而是通过ReportFragment来代为转发生命周期事件。

先看SupportActivity的onCreate()方法:

1
2
3
4
5
6
7
8
public class SupportActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
}

再看ReportFragment的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class ReportFragment extends Fragment {

// 将ReportFragment add到宿主上去,这样就可以监听宿主的生命周期
public static void injectIfNeededIn(Activity activity) {
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
// 将宿主Activity的生命周期变化分发出去
dispatch(Lifecycle.Event.ON_CREATE);
}

private void dispatch(Lifecycle.Event event) {
Activity activity = getActivity();
// ...
// 取得宿主并分发宿主Activity的生命周期变化
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}

// 还有其他的生命周期方法,实现都和onActivityCreated()一样,不再列出

}

看到这里可能会疑惑为什么要引入ReportFragment,本人猜测的原因是,如果你项目中使用的BaseActivity并没有继承自support包,那么你就可以将ReportFragment添加到你的BaseActivity,这样它就也有生命周期的功能了。而SupportActivity刚好提供了这样的一种实现的范例。

注解是如何在Lifecycle中工作的?

Lifecycle除了直接使用GenericLifecycleObserver提供的接口进行状态获取,还可以通过直接实现LifecycleObserver接口并配合OnLifecycleEvent注解来实现指定方法在收到生命周期时间后的自动调用。

使用注解与直接使用监听器的区别在于注册的逻辑与后续的事件接收逻辑略有不同,其他的部分基本一致,因此这里只看这两部分是如何实现的。

1、利用注解完成注册:

直接看ObserverWithState的代码:

1
2
3
4
5
6
7
8
9
10
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;

ObserverWithState(LifecycleObserver observer, State initialState) {
// 在这里对注解进行处理
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
}

具体的注解处理可以查看Lifecycling.getCallback(observer);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@NonNull
static GenericLifecycleObserver getCallback(Object object) {
// 过滤掉两种非注解的实现
if (object instanceof FullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
}
if (object instanceof GenericLifecycleObserver) {
return (GenericLifecycleObserver) object;
}

final Class<?> klass = object.getClass();
// 这里的type有REFLECTIVE_CALLBACK与GENERATED_CALLBACK两种,
// 分别代表注解的处理方式不同的两种Observer,
// 前者代表反射,后者代表APT,这里只分析反射,APT的部分读者有兴趣可以自己去看
int type = getObserverConstructorType(klass);
if (type == GENERATED_CALLBACK) {
// ...
return new CompositeGeneratedAdaptersObserver(adapters);
}
return new ReflectiveGenericLifecycleObserver(object);
}

这里只关注与反射处理注解相关的代码,接下来跟进去看resolveObserverCallbackType()的实现:

1
2
3
4
5
6
7
8
9
private static int resolveObserverCallbackType(Class<?> klass) {
// ...
// 这一步根据注解信息取出哪些方法被注解标记了
boolean hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass);
if (hasLifecycleMethods) {
return REFLECTIVE_CALLBACK;
}
// ...
}

最核心的实现在hasLifecycleMethods()方法中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class ClassesInfoCache {
private final Map<Class, CallbackInfo> mCallbackMap = new HashMap<>();
private final Map<Class, Boolean> mHasLifecycleMethods = new HashMap<>();

boolean hasLifecycleMethods(Class klass) {
// 优先取缓存,提高效率
if (mHasLifecycleMethods.containsKey(klass)) {
return mHasLifecycleMethods.get(klass);
}

Method[] methods = getDeclaredMethods(klass);
for (Method method : methods) {
OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
if (annotation != null) {
// 提取必要的方法信息并存储
createInfo(klass, methods);
return true;
}
}
mHasLifecycleMethods.put(klass, false);
return false;
}
}

到此为止,就完成了根据传入的LifecycleObserver,注册它,并记录其需要相应生命周期事件的函数的任务。

2、利用缓存的方法信息完成消息发送

回去看前面getCallback()的实现,可以发现它返回了ReflectiveGenericLifecycleObserver,再看其实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ReflectiveGenericLifecycleObserver implements GenericLifecycleObserver {
private final Object mWrapped;
private final CallbackInfo mInfo;

ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
}

@Override
public void onStateChanged(LifecycleOwner source, Event event) {
mInfo.invokeCallbacks(source, event, mWrapped);
}
}

显然其实现就是通过ClassesInfoCache缓存的信息调用对应的被注解标记的方法,细节也不复杂,就不展开了。

其他

上面讨论的源码都是围绕Lifecycle的基础功能的,实际上Lifecycle的extensions包中提供了更丰富的生命周期组件。包括拥有生命周期的服务LifecycleService和提供Application生命周期的组件ProcessLifecycleOwner,具体的使用和源码分析这里不再展开了,有兴趣的可以自己去查询相关资料。

参考资料

Handling Lifecycles with Lifecycle-Aware Components