Android官方提供了一系列架构组件,其名曰 jetpack。本文从源码的角度深入理解 Lifecycle 组件的原理。
一、使用介绍
Lifecycle 组件是官方架构组件的基石,很多组件也是依赖它来实现的。它能感知Activity/Fragment(或你的自定义组件)的生命周期并且将生命周期状态通知给其他对象。
很多开发者一定有这样的经历,一个Activity/Fragment的各个生命周期方法内处理大量的业务逻辑代码,有了 Lifecycle 我们就可以将任意的业务逻辑拆分,单独写到一个类中。
以下是使用示例:
class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getLifecycle().addObserver(new LearnLifecycleObserver());
}
}
/**
* 学习LifecycleObserver
* @author sunxianglei
* @date 2019/05/30
*/
public class LearnLifecycleObserver implements LifecycleObserver {
private static final String TAG = "LearnLifecycleObserver";
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void discoverLifecycle(){
Log.d(TAG, "I discover lifecycle component, it looks well");
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void startLearn(){
Log.d(TAG, "I start to learn lifecycle, I see see if it's really well");
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void stopLearn(){
Log.d(TAG, "what a fu*k! it's too difficult, I give up");
}
}
Lifecycle 的使用还是很简单的,但是如果不知道其实现原理,你就无法灵活的排查问题、理解其他的组件,所以我们需要看源码。
二、源码分析
提出问题
大佬说过,看源码一定要带着问题去看,只要将问题原理搞清楚了就可以出来了,不要沉迷于源码细节,很容易迷失自己。根据上面的示例,自定义类实现了 LifecycleObserver 接口,然后将其对象添加到Lifecycle 中。我对此提出两个疑问:
Lifecycle是什么,添加LifecycleObserver的流程是怎样的?- Activity/Fragment生命周期状态貌似看起来是通过注解通知到对应的方法,那这个分发过程是怎样的呢?
接下来就带着问题去看源码了。
Tips: debug 看调用堆栈是个很不错的手段。
1. Lifecycle及添加LifecycleObserver的流程
第一步肯定是跟getLifecycle()方法,这个方法是 LifecycleOwner 的一个接口方法(通过实现 LifecycleOwner 接口可以制作一个自定义管理生命周期分发的组件,这个本文不讨论)。然后你会发现 Android 系统源码在 SupportActivity 类实现了这个接口,在 SupportActivity类中有个 mLifecycleRegistry对象,然后发现LifecycleRegistry继承了Lifecycle抽象类,直接贴出代码:
public abstract class Lifecycle {
public abstract void addObserver(@NonNull LifecycleObserver observer);
public abstract void removeObserver(@NonNull LifecycleObserver observer);
public abstract State getCurrentState();
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED
}
}
每个方法和变量其实都有详细的注释,看下注释基本能明白他们的作用。贴一下官方的生命周期状态和事件图:
**State 是节点, Event 是连接每个节点的线。**Event 的状态完全可以按 Activity 的生命周期来理解,都是一一对应的,State 看起来是缺失了 PAUSED、STOPED,其实它的 PAUSED 就是 STARTED,STOPED 是 CREATED。总的来说,Event 就是改变生命周期的事件,State 是目前 Activity/Fragment 所处生命周期的状态。
LifecycleRegistry作为Lifecycle 的唯一实现类,是相当关键的一个类,先看下它是如何添加自定义LifecycleObserver的。
public void addObserver(LifecycleObserver observer){
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
......
}
这段代码创建了 ObserverWithState 对象,并将 LifecycleObserver 和ObserverWithState 对象通过构造方法传进去,然后以键值对的形式将LifecycleObserver作为key, ObserverWithState作为value进行存储。接着看下 ObserverWithState 构造方法内做了什么事:
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
}
再跟进 getCallBack 方法内会发现最后返回对象是new ReflectiveGenericLifecycleObserver, ReflectiveGenericLifecycleObserver 实现了 GenericLifecycleObserver 接口,它的构造方法内保存了我们自定义的LifecycleObserver,并且解析生成一个 CallbackInfo 对象,我们可以把这个类理解成自定义LifecycleObserver的包装类。
class ReflectiveGenericLifecycleObserver implements GenericLifecycleObserver {
private final Object mWrapped;
private final CallbackInfo mInfo;
ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
}
}
暂时就先跟到这里吧,因为我们的目的就是了解 Lifecycle 抽象类是个什么东西,是如何添加自定义Observer的,根据上面的源码阅读就能回答了。
Lifecycle 管理着组件(Activity/Fragment)的生命周期事件和状态,LifecycleRegistry 是其唯一实现类,真正的添加操作发生在addObserver() 方法内,主要是构造出ObserverWithState 对象,其内部包装 ReflectiveGenericLifecycleObserver 对象,而 ReflectiveGenericLifecycleObserver 包装自定义Observer对象,然后将ObserverWithState对象放到集合中,之后会使用到。
2. 生命周期事件分发
既然是生命周期事件分发,那肯定得看生命周期方法吧,先看下SupportActivity.OnCreate方法发现它创建了一个 ReportFragment,这是个空白的Fragment,主要用来分发生命周期的,果不其然,ReportFragment 内部的生命周期方法都分发了Event:
// ReportFragment
// 不同的生命周期方法会调用此方法,传进不同的Event
private void dispatch(Lifecycle.Event event) {
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
// LifecycleRegistry
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
//该方法将Event转成State,正好对应之前Event和State那张关系图
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;
}
}
moveToState 方法内会调用到 sync() 方法:
private void sync() {
......
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;
}
根据 State 的状态会有前进、后退两种逻辑,前进就是生命周期状态和事件图中从左往右的线路,后退就是生命周期状态和事件图从右往左的线路,看下比较难理解的后退逻辑:
private void backwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
mObserverMap.descendingIterator();
// 第一层循环:遍历所有的自定义LifeObserver
while (descendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
ObserverWithState observer = entry.getValue();
// 第二层循环:根据当前Activity/Fragment的生命周期状态
// 对比自定义LifecycleObserver所处的状态,然后按状态顺序一层层的更新状态
while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
Event event = downEvent(observer.mState);
pushParentState(getStateAfter(event));
// 调用 ObserverWithState.dispatchEvent
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
// 此方法是将State按后退逻辑转换成对应的Event
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();
}
}
接下来走到ObserverWithState.dispatchEvent方法,之前说到过 ObserverWithState 是 ReflectiveGenericLifecycleObserver 的包装类。
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
// 调用 ReflectiveGenericLifecycleObserver.OnStateChanged 方法
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
之前还说到过 ReflectiveGenericLifecycleObserver 是自定义LifecycleObserver的包装类,感觉这里即将要分发到LifecycleObserver里去了啊!
public void onStateChanged(LifecycleOwner source, Event event) {
mInfo.invokeCallbacks(source, event, mWrapped);
}
其实调用CallbackInfo.invokeCallBacks基本就要结束了,不过我们还不知道 CallbackInfo 是怎么来的, 这也是上节遗留的一个疑点,即在 ReflectiveGenericLifecycleObserver 构造方法内调用了这么一句mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass()); 进去看看 CallbackInfo 是怎么创建的:
private CallbackInfo createInfo(Class klass, @Nullable Method[] declaredMethods) {
// MethodReference 和 Lifecycle.Event HashMap集合,
// 每个自定义LifecycleObserver的method对应一个Event,可以有多个method用同样的Event
Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>();
Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);
for (Method method : methods) {
// 解析注解
OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
if (annotation == null) {
continue;
}
Lifecycle.Event event = annotation.value();
MethodReference methodReference = new MethodReference(callType, method);
// handlerToEvent集合添加对应的method和Event键值对
verifyAndPutHandler(handlerToEvent, methodReference, event, klass);
}
// CallbackInfo构造方法内进一步针对一种Event对应多个Method的情况,整理成一个HashMap
CallbackInfo info = new CallbackInfo(handlerToEvent);
return info;
}
上述代码省略了一些不重要的代码,MethodReference对象其实完全可以看做是 Method,前者是后者的包装类。然后我们回到 ReflectiveGenericLifecycleObserver.onStateChanged 方法中,里面调用了CallbackInfo.invokeCallbacks()
void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
// 根据Event拿到一组注解了此Event的方法,然后遍历调用。
invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);
invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,
target);
}
private static void invokeMethodsForEvent(List<MethodReference> handlers,
LifecycleOwner source, Lifecycle.Event event, Object mWrapped) {
if (handlers != null) {
for (int i = handlers.size() - 1; i >= 0; i--) {
handlers.get(i).invokeCallback(source, event, mWrapped);
}
}
}
// MethodReference.invokeCallback 方法进去就是真正调用 Method.invoke 方法的地方
void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {
switch (mCallType) {
case CALL_TYPE_NO_ARG:
// 没有参数的方法会调到这里
mMethod.invoke(target);
break;
case CALL_TYPE_PROVIDER:
mMethod.invoke(target, source);
break;
case CALL_TYPE_PROVIDER_WITH_EVENT:
mMethod.invoke(target, source, event);
break;
}
}
到此为止,一次生命周期事件分发就结束了。
每次 ReportFragment 生命周期状态的变化会分发Lifecycle.Event,接着调到 LifycycleRegistry 根据目前生命周期状态和之前状态对比来决定是前进还是后退,然后会经过 ObserverWithState->ReflectiveGenericLifecycleObserver -> CallbackInfo -> MethodReference,最终通过反射真正调用到自定义LifecycleObserver添加了注解的方法。
三、总结
大佬说过,看源码一定要画类图和时序图,配合源码食用会更加美味。
类图:
时序图:
根据以上两张图做一个总结:
SupportActivity实现了LifecycyleOwner,并通过getLifecycle()方法获得Lifecycle唯一实现类LifecycleRegistry的实例,这时我们就可以通过addObserver方法添加我们想要感知生命周期的自定义对象了。而且我们也可以按照这种模式,自己写一个实现了LifecycleOwner接口的组件。- 添加自定义
LifecycleObserver对象后,这个对象就会被ReflectiveGenericLifecycleObserver包装,同时会通过解析方法注解生成一个CallbackInfo用作后期的Event分发,ReflectiveGenericLifecycleObserver又会被ObserverWithState包装,ObserverWithState加入一个集合后就代表生命周期状态改变时会通知到所有的LifecycleObserver。 SupportActivity.OnCreate方法中会创建一个空白ReportFragment,当它的生命周期State改变时会结合之前的State做对比决定是前进还是后退State,然后会依次调用ObserverWithState -> ReflectiveGenericLifecycleObserver.onStateChanged -> CallbackInfo.invokeCallbacks -> MethodReference.invokeCallback,最后会调到LifecycleObserver注解了Lifecycle.Event的方法中。
参考资料