Lifecycle,更新UI的好帮手

发布于 2022年 05月 04日 21:45

使用实例

Activity中的注册语句:getLifecycle().addObserver(LifecycleObserver)

getLifecycle().addObserver(new LifecycleObserver() {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void aa() {
        Log.i("kobe", "LifecycleObserver ");
    }
});

在方法上添加注解,这里以ON_RESUME为例,当Activity的onResume被调用时,aa()会执行,日志被打印。

注册过程

getLifecycle().addObserver(),getLifecycle部分

getLifecycle是LifecycleOwner的接口方法,在Activity中调用,存在继承关系。
androidx.appcompat.app.AppCompatActivity implements LifecycleOwner
androidx.fragment.app.FragmentActivity
androidx.core.app.ComponentActivity

  • androidx.activity.ComponentActivity.java
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    public Lifecycle getLifecycle() {
    return mLifecycleRegistry;
}

LifecycleRegistry的引用在ComponentActivity中申明,且什么时即完成初始化。
LifecycleRegistry的入参就是Activity本身,lifecycle使用观察者模式,activity是内容提供者,是被观察者。
LifecycleRegistry与Activity是一一对应的关系,LifecycleRegistry用于管理当前Activity和这个Activity的观察者。
LifecycleRegistry的成员:
mState:是LifeCycleRegistry的状态。

getLifecycle().addObserver(),addObserver部分

  • androidx.lifecycle.LifecycleRegistry.java
int mAddingObserverCounter; // 记录有多少个观察者
public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
    ... // 后面貌似是做一个类似粘性事件的东西
}

ObserverWithState把mState与Observer封装起来;
mObserverMap是一个map,key是Observer,而value是前面封装后的ObserverWithState。

Activity的生命周期方法执行,怎么通知到观察者

通知的发起

Activity生命周期变化时,即生命周期方法执行时,会通知Lifecycle。但其实这个通知过程的发起不是Activity,而是借助于其内部的一个不可见的Fragment完成的。我猜因为Fragment与Activity的生命周期高度耦合,而降低Activity的职责,所以通知的发起就由ReportFragment代劳了。
Activity内添加了一个不可见的Fragment,如下:

  • androidx.core.app.ComponentActivity
onCreate() {
    ReportFragment.injectIfNeededIn(this); // 将这个ReportFragment添加到Activity,过程略
}

当Activity生命周期变化时,Fragment的生命周期也会变化,不论Fragment是否可见。举例就是,A、B两个Fragment,当前显示的是A,当Activity执行onResume,或者其他生命周期方法,B的也会执行。
当ReportFragment的生命周期方法执行时,会调用dispatch把生命周期变化发送出去。也只有生命周期方法会调用dispatch(),所以Lifecycle无法监听到Fragment的show、hide。

  • ReportFragment.java
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    ...
    dispatch(Lifecycle.Event.ON_CREATE);
}

@Override
public void onStart() {
    ...
    dispatch(Lifecycle.Event.ON_START);
}

@Override
public void onResume() {
    ...
    dispatch(Lifecycle.Event.ON_RESUME);
}

private void dispatch(Lifecycle.Event event) {
    Activity activity = getActivity();
    if (activity instanceof LifecycleOwner) { // ComponentActivity实现LifecycleOwner,所以进入这个分支
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        if (lifecycle instanceof LifecycleRegistry) {
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
        }
    }
}

通知的过程

dispatchLifecycleRegistry.handleLifecycleEventmoveToStatesyncforwardPass|backwardPassobserver.dispatchEvent(LifecycleRegistry$ObserverWithState) 》 mLifecycleObserver.onStateChanged【 mLifecycleObserver是LifecycleEventObserver,具体应该是ReflectiveGenericLifecycleObserver,这个挖一个坑(为什么mLifecycleObserver是ReflectiveGenericLifecycleObserver)】 》 ReflectiveGenericLifecycleObserver.onStateChangedmInfo.invokeCallbacksinvokeMethodsForEventmInfo.invokeCallbacks,invokeCallbacks中通过反射调用被@LifecycleEvent标记的方法。

为什么mLifecycleObserver是ReflectiveGenericLifecycleObserver

mLifecycleObserver.onStateChanged这一句,mLifecycleObserver的申明类型是GenericLifecycleObserver(GenericLifecycleObserver extends LifecycleObserver),而GenericLifecycleObserver的子类众多,为什么是ReflectiveGenericLifecycleObserver呢?
在LifecycleRegistry.addObserver()方法中,LifecycleObserver将会被封装为ObserverWithState,如下:

  • LifecycleRegistry$ObserverWithState.java
static class ObserverWithState {
    LifecycleEventObserver mLifecycleObserver;
    ObserverWithState(LifecycleObserver observer, State initialState) {
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
    }
    void dispatchEvent(LifecycleOwner owner, Event event) {
    ...
    mLifecycleObserver.onStateChanged(owner, event);
    }
}

具体的封装过程由Lifecycling.lifecycleEventObserver()完成。

  • Lifecycling.java
static LifecycleEventObserver lifecycleEventObserver(Object object) {
    ...
    final Class klass = object.getClass();
    int type = getObserverConstructorType(klass);
    if (type == GENERATED_CALLBACK) { // 此分支不满足
        ...
        return new CompositeGeneratedAdaptersObserver(adapters);
    }
    return new ReflectiveGenericLifecycleObserver(object);
}

如上,条件不满足,所以走最后的ReflectiveGenericLifecycleObserver。这个决定条件是type = getObserverConstructorType()的值,其存在如下调用关系:
getObserverConstructorType 》 resolveObserverCallbackType。

  • Lifecycling.java
private static int resolveObserverCallbackType(Class klass) {
    Constructor constructor = generatedConstructor(klass); // 返回null,懒得贴源码和分析了
    if (constructor != null) {
        return GENERATED_CALLBACK;
    }
    boolean hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass);
    if (hasLifecycleMethods) {
        return REFLECTIVE_CALLBACK;
    }
    ...
    }

这里应该返回REFLECTIVE_CALLBACK,所以上面的LifecycleObserver mLifecycleObserver应该为ReflectiveGenericLifecycleObserver类型,这是用了装饰者模式。
上面ClassesInfoCache.sInstance.hasLifecycleMethods()是个很重要的方法,后面会分析到。

mInfo.invokeCallbacks,mInfo的来源。

mInfo的类型是ClassesInfoCache.CallbackInfo,这是一个内部类。
上面的调用流程到了mInfo.invokeCallbacks,mInfo的类型是CallbackInfo,怎么来的。
LifecycleObserver是会被封装成ReflectiveGenericLifecycleObserver,看封装过程,也就是ReflectiveGenericLifecycleObserver的构造方法。

  • ReflectiveGenericLifecycleObserver.java
ReflectiveGenericLifecycleObserver(Object wrapped) { // 这个wrapped就是Lifecycle的对象
    mWrapped = wrapped;
    mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
}
  • ClassesInfoCache.java
CallbackInfo getInfo(Class klass) { // klass是Lifecycle,或者其子类
    CallbackInfo existing;
    existing = createInfo(klass, null);
}

private CallbackInfo createInfo(Class klass, @Nullable Method[] declaredMethods) {
    /* Method到event的映射,虽然是个局部变量,但还是很重要的 */
    Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>();
    // declaredMethods作为入参,传入的实参是null,这里走后面的getDeclaredMethods(klass),获取方法
    Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);
    boolean hasLifecycleMethods = false;
    /*
    * 1、找到被@OnLifecycleEvent注解的方法
    * 2、把这个方法添加到handlerToEvent中。——handlerToEvent是个map,是Method到Event的映射。
    */
    for (Method method : methods) {
        OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
        if (annotation == null) {
            continue;
        }
        MethodReference methodReference = new MethodReference(callType, method); // 对Method封装
        verifyAndPutHandler(handlerToEvent, methodReference, event, klass);
    }
    /*
    * 把LifecycleObserver中的方法(@LifecycleEvent)找到,用handlerToEvent管理;
    * ClassInfoCache内还有两个map,mCallbackMap和mHasLifecycleMethods,他们把handlerToEvent管理起来,key都是LifecycleObserver这个class
    */
    CallbackInfo info = new CallbackInfo(handlerToEvent);
    mCallbackMap.put(klass, info);
    mHasLifecycleMethods.put(klass, hasLifecycleMethods);
    return info;
}

看一下CallbackInfo的构造方法

在这个构造方法中,把前面的局部变量————Method到Event的映射,用类变量保存起来;遍历Method到Event的映射,然后建立一个Event到Method的映射。为什么呢?因为观察者模式,是观察provider(被观察者)的事件的,建立了Event到Method的映射,当Event发生时,很方便就找到Method就执行了。然后Method为什么用List呢,因为LifecycleObserver中是可以写多个方法,然后监听同一个事件的,即这些方法都是用@Lifecycle.Event.ON_RESUME注解。

  • CallbackInfo.java ———— ClassesInfoCache$CallbackInfo
final Map<Lifecycle.Event, List<MethodReference>> mEventToHandlers;

CallbackInfo(Map<MethodReference, Lifecycle.Event> handlerToEvent) {
    mHandlerToEvent = handlerToEvent;
    mEventToHandlers = new HashMap<>();
    for (Map.Entry<MethodReference, Lifecycle.Event> entry : handlerToEvent.entrySet()) {
        Lifecycle.Event event = entry.getValue();
        List<MethodReference> methodReferences = mEventToHandlers.get(event);
        if (methodReferences == null) {
            methodReferences = new ArrayList<>();
            mEventToHandlers.put(event, methodReferences);
        }
        methodReferences.add(entry.getKey());
    }
}

mInfo.invokeCallbacks,invokeCallbacks调用流程

invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target); invokeMethodsForEvent(List handlers, LifecycleOwner source, Lifecycle.Event event, Object mWrapped);
handlers.get(i).invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target);
mMethod.invoke(...);

看invokeMethodsForEvent的入参,invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target),mEventToHandlers是Event到Method(准确说是Method的List)的映射,用get得到这个List,所以后面handlers.get(i)就得到了Method对象,invoke就执行了。

State的作用

LifecycleRegistry$ObserverWithState.mState

这个State跟Observer一一对应的,且略延后。当一个Event过来并处理完毕后,ObServer(所有的Observer)记录这个State,下一个Event过来时,比较(min),然后满足条件的才会继续处理,详见forwardPass|backwardPass。

Fragment的生命周期方法执行,怎么通知到

注册时必须调用getLifecycle().addObserver(),Fragment自己实现了LiftcycleOwner。

  • androidx.fragment.app.Fragment.java
class Fragment implements LifecycleOwner {
    LifecycleRegistry mLifecycleRegistry;
    public Fragment() {
        initLifecycle();
    }

    private void initLifecycle() {
        mLifecycleRegistry = new LifecycleRegistry(this);
    }

    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
}

流程:Fragment.perforStart 》 mLifecycleRegistry.handleLifecycleEvent,剩下的和Activity的一样。

小结

当数据变化时,更新UI。但是处于隐藏状态的Activity,需要我们判断;然后还有已经发生内存溢出的Activity,更新UI可能导致崩溃。Lifecycle有效帮我们从这些复杂的判断解脱出来,也一定程度避免了崩溃的发生。
Lifecycle应该是和Eventbus互补,我看有的在线教育讲师说Lifecycle取代Eventbus,我不认可。Lifecycle只会在生命周期变化时才会驱动通知,Eventbus无论何时都行;Lifecycle的驱动发起者只能是Activity和Fragment,Eventbus无论什么都行。
在数据变化后通知刷新UI,Lifecycle更好用,但除此之外,Eventbus仍有无可比拟的优势。
另外,对应Fragment的show、hide,Lifecycle无法感知。

然后看了一些框架的源码,感觉说到底,还是设计模式、数据结构、反射、注解这些最基本的java知识。尤其是反射和注解,像Eventbus、Retrofit、Butterknife等都是如此。理解这些,方便便于我们理解框架。我在阅读源码过程中,也是需要不停百度、或者查看api才知道某一句话意思,知道为什么走这个分支。

最后,我想到达2级,这样可以给文章添加两个标签,所以请觉得文章有用的同学,帮点一个赞,谢谢。

推荐文章