Jetpack学习之 Lifecycle

网友投稿 283 2022-09-21

Jetpack学习之 Lifecycle

​​Lifecycle​​​ 用于帮助开发者管理 Activity 和 Fragment 的生命周期,由于 Lifecycle 是 ​​LiveData​​​ 和 ​​ViewModel​​的基础, 所以要了解后面那两位,需要先学习 Lifecycle。

目录

​​1. 概述​​

​​1.1 Lifecycle定义​​​​1.2 为什么使用Lifecycle​​

​​2. 使用​​

​​2.1 导入​​​​2.2 简单示例​​​​2.3 *自定义 LifecycleOwner​​

​​3. 原理​​

​​3.1 Lifecycle 的生命周期状态事件和状态​​​​3.2 Lifecycle 是如何观察生命周期的​​​​3.3 Lifecycle UML图​​

​​参考文章​​

1. 概述

1.1 Lifecycle定义

Lifecycle 组件用来感知另外一个组件(Activity、Application、Fragment)的生命周期。

1.2 为什么使用Lifecycle

我们代码是能够直接访问组件的生命周期相关的方法的,为什么还要特意去用 Lifecycle 来感知它?

来看看下面这段代码:

class MainActivity : AppCompatActivity() { val listener = Listener() ... override fun onStart() { listener.onStart() } override fun onResume() { listener.onResume() } override fun onStop() { listener.onStop() } class Listener { fun onStart()... fun onResume()... fun onStop()... }}

上面的代码还可以把 Listener 换成MVP中的 Presenter。

这种写法比较普遍也不难,但是我们平时开发中,不可能只是单单这样子调用那么简单。如果出现了多种组件需要依赖Activity、Fragment生命周期的场景,那么在它们生命周期的方法中,就可能需要写入大量的代码,这使得它们难以维护。

如果我们在组件中做了耗时操作(比如 onStart 方法),那么这种写法就无法保证组件在 Activity 或者 Fragment 停止之前完成启动。因此我们需要一个能够管理 Activity 和 Fragmgent 的生命周期的库, 这个库就是 Lifecycle。

2. 使用

2.1 导入

下面是官方文档给出的导入配置,比较全,可以选其中的几个导入就行了:

dependencies { def lifecycle_version = "2.3.0" def arch_version = "2.1.0" // ViewModel implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" // LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" // Lifecycles only (without ViewModel or LiveData) implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" // Saved state module for ViewModel implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version" // Jetpack Compose Integration for ViewModel implementation "androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha01" // Annotation processor kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" // alternately - if using Java8, use the following instead of lifecycle-compiler implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" // optional - helpers for implementing LifecycleOwner in a Service implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version" // optional - ProcessLifecycleOwner provides a lifecycle for the whole application process implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version" // optional - ReactiveStreams support for LiveData implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version" // optional - Test helpers for LiveData testImplementation "androidx.arch.core:core-testing:$arch_version"}

2.2 简单示例

我们需要创建一个 Lifecycle,来观察一个 Activity,如下所示:

class MainObserver: LifecycleObserver { companion object { private const val TAG = "MainObserver" } // 1 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun connect() { Log.d(TAG, "connect") } // 2 @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun disconnect() { Log.d(TAG, "disconnect") } }

MainObserver 继承自 ​​LifecycleObserver​​​ ,表明成为一个 Lifecycle 的观察者。 注释1:通过 ​​​@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)​​​ 来观察组件的 Resume 状态 注释2:通过 ​​​@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)​​​ 来观察组件的 Pause 状态 接下来要将它观察指定的Activity。

AndroidX 的 ​​AppCompatActivity​​​ 继承了 ​​ComponentActivity​​​,后者实现了 ​​getLifecycle()​​方法,所以我们可以在 Activity(需要继承)中直接获取当前组件的 Lifecycle,所以可以看下下面的代码:

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 1 lifecycle.addObserver(MainObserver()) }}

在注释一处, 通过 ​​getLifecycle()​​​ 获取到当前组件的 Lifecycle,接下来可以通过其 ​​addObserver()​​​ 方法,将 MainObserver 添加到 ​​LifecycleOwner​​ 中了。

LifecycleOwner 是一个接口,它只有一个 ​​getLifecycle()​​ 方法,而 ComponentActivity 实现了它,所以我们可以调用这个方法。获取它后,可以添加观察者进去,当生命周期发生变化时, MainObserver 就能感知。接下来我打开 MainActivity,或者放到后台,就会下面这个Log:

2.3 *自定义 LifecycleOwner

因为只有 Support26.1.0+ 、 AndroidX 的版本是在 Activity、Fragment中实现了 LifecycleOwner 接口,所以这些版本的代码中,可以通过 ​​getLifecycle()​​ 来获取 Lifecycle。

但是非这些版本,就需要开发者自己手动实现,具体使用需要使用 ​​LifecycleRegistry​​ 这个类。但是我认为这种场景是已经比较少了,所以这里就不多赘述。

3. 原理

3.1 Lifecycle 的生命周期状态事件和状态

Lifecyce 使用 两个枚举 来跟踪其关联组件的生命周期状态, 它们分别是: ​​Event​​​ 和 ​​Status​​。

State 代表 Lifecycle 的生命周期所处的状态Event 代表 Lifecycle 生命周期对应的事件

这些事件会映射到 Activity 和 Fragment的回调事件中。

来看下 Lifecycle 的部分源码:

public abstract class Lifecycle { public abstract void addObserver(@NonNull LifecycleObserver observer); public abstract void removeObserver(@NonNull LifecycleObserver observer); @SuppressWarnings("WeakerAccess") 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; public boolean isAtLeast(@NonNull State state) { return compareTo(state) >= 0; } }}

Lifecycle 是一个抽象类,提供了 add 和 remove 观察者的方法,还定义了 Event 和 Status 两个枚举。

可以看到 Event 中的事件和 Activity 的生命周期几乎是对应的,还有一个 ​​ON_ANY​​,和它名字一样,用来匹配所有的事件。

Status 与 Events 的关系如下图所示:

3.2 Lifecycle 是如何观察生命周期的

因为 MainActivity 继承了 ​​ComponentActivity​​,它实现了 Lifecycler接口,所以我们可以看看它是如何实现该接口的。下面是一个调用链时序图:

// ComponentActivity.javapublic class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner, ... { // 1 private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { ... // 2 ReportFragment.injectIfNeededIn(this); } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { // 3 Lifecycle lifecycle = getLifecycle(); if (lifecycle instanceof LifecycleRegistry) { ((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED); } ... } @Override public Lifecycle getLifecycle() { // 4 return mLifecycleRegistry; }}

注释1:创建了 ​​LifecycleRegistry​​, 它是 Lifecycle 的实现类。 注释4实现接口方法,并返回了这个实例。

注释3: 在 ​​onSaveInstanceState()​​​ 方法中, 使用 LifecycleRegistry 标记当前的 State 为 ​​CREATED​​​。 正常来说,ComponentActivity 会在每个生命周期方法中,都会去标记下State,但是我们发现它并没有这样做。 而是交给了 注释2中的 ​​​ReportFragment​​ 来处理。

注释2:将 ComponentActivity 注入到 ReportFragment 中:

// ReportFragment.javapublic class ReportFragment extends android.app.Fragment { public static void injectIfNeededIn(Activity activity) { if (Build.VERSION.SDK_INT >= 29) { LifecycleCallbacks.registerIn(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(); } } static ReportFragment get(Activity activity) { return (ReportFragment) activity.getFragmentManager().findFragmentByTag( REPORT_FRAGMENT_TAG); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); dispatchCreate(mProcessListener); dispatch(Lifecycle.Event.ON_CREATE); } @Override public void onStart() { super.onStart(); dispatchStart(mProcessListener); // 1 dispatch(Lifecycle.Event.ON_START); } @Override public void onResume() { super.onResume(); dispatchResume(mProcessListener); dispatch(Lifecycle.Event.ON_RESUME); } @Override public void onPause() { super.onPause(); dispatch(Lifecycle.Event.ON_PAUSE); } @Override public void onStop() { super.onStop(); dispatch(Lifecycle.Event.ON_STOP); } @Override public void onDestroy() { super.onDestroy(); dispatch(Lifecycle.Event.ON_DESTROY); mProcessListener = null; } private void dispatch(@NonNull Lifecycle.Event event) { if (Build.VERSION.SDK_INT < 29) { dispatch(getActivity(), event); } } void setProcessListener(ActivityInitializationListener processListener) { mProcessListener = processListener; } interface ActivityInitializationListener { void onCreate(); void onStart(); void onResume(); } static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) { // 2 if (activity instanceof LifecycleRegistryOwner) { ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event); return; } // 3 if (activity instanceof LifecycleOwner) { Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle(); if (lifecycle instanceof LifecycleRegistry) { ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); } } } ...}

ReportFragment 的 ​​onStart()​​​ 方法中会调用注释 1 处的 ​​dispatch()​​。

该方法中,注释2处:判断 Activity 是否实现了 ​​LifecycleRegistryOwner​​​ 接口。该接口和 ​​LifecyclerOwner​​ 的不同之处,就是前者 getLifecycle() 返回的是 LifecycleRegistry 实例,后者返回的是 Lifecycle实例。

注释3: 如果 Activity 继承了 LifecycleOwner 接口,则调用 LifecycleRegistry 的 ​​handleLifecycleEvent()​​ 方法,也就是说 注释2 和 3 所做的事情是一样的。

来看看 ​​handleLifecycleEvent()​​ 方法:

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {、 moveToState(event.getTargetState()); } public State getTargetState() { switch (this) { case ON_CREATE: case ON_STOP: return State.CREATED; case ON_START: case ON_PAUSE: return State.STARTED; case ON_RESUME: return State.RESUMED; case ON_DESTROY: return State.DESTROYED; case ON_ANY: break; } throw new IllegalArgumentException(this + " has no target state"); }

它会调用 Event ​​getTargetState()​​ 方法,来获取当前Event所映射的State。这个和上面的映射表一致。

接着调用 ​​moveToState()​​:

private void moveToState(State next) { if (mState == next) { return; } mState = next; if (mHandlingEvent || mAddingObserverCounter != 0) { mNewEventOccurred = true; return; } mHandlingEvent = true; sync(); mHandlingEvent = false; }

这里主要是调用了 ​​sync()​​ 方法:

private void sync() { LifecycleOwner lifecycleOwner = mLifecycleOwner.get(); ... while (!isSynced()) { mNewEventOccurred = false; // 当前状态 - 最早的状态<0 ,表明当前状态是向后的 if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) { backwardPass(lifecycleOwner); } // 当前状态 - 最新的状态>0 ,表明当前状态是向前的 Map.Entry newest = mObserverMap.newest(); if (!mNewEventOccurred && newest != null && mState.compareTo(newest.getValue().mState) > 0) { forwardPass(lifecycleOwner); } } mNewEventOccurred = false; }

​​sync()​​ 方法会根据当前状态和 mObserverMap 中的 eldest 和 newest 的状态进行对比,判断当前的状态是向前的还是向后的。 比如 STARTED -> RESUMED 是状态向前,反过来是向后的。

无论向前还是向后,代码都是差不多的,这里以 ​​backwardPass()​​ 为例:

private void backwardPass(LifecycleOwner lifecycleOwner) { Iterator> descendingIterator = mObserverMap.descendingIterator(); while (descendingIterator.hasNext() && !mNewEventOccurred) { Map.Entry entry = descendingIterator.next(); // 1 ObserverWithState observer = entry.getValue(); while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred && mObserverMap.contains(entry.getKey()))) { Event event = Event.downFrom(observer.mState); if (event == null) { throw new IllegalStateException("no event down from " + observer.mState); } pushParentState(event.getTargetState()); // 2 observer.dispatchEvent(lifecycleOwner, event); popParentState(); } } }

注释1: 获取了 ​​ObserverWithState​​ 实例

注释2: 执行注释1实例的 dispatchEvent,传入的 event 代表的是当前状态的向后状态

来看看那 ​​ObserverWithState.dispatchEvent()​​:

class ObserverWithState { State mState; LifecycleEventObserver mLifecycleObserver; ObserverWithState(LifecycleObserver observer, State initialState) { mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer); mState = initialState; } void dispatchEvent(LifecycleOwner owner, Event event) { State newState = event.getTargetState(); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; } }

该类包含了 State 和 LifecycleEventObserver,后者是一个接口,继承了 LifecycleObserver~ 而 ​​​ReflectiveGenericLifecycleObserver​​ 则是它的一个实现类,来看看它是如何实现的:

class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver { private final Object mWrapped; private final CallbackInfo mInfo; ReflectiveGenericLifecycleObserver(Object wrapped) { mWrapped = wrapped; mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass()); } @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) { // 1 mInfo.invokeCallbacks(source, event, mWrapped); }}

注释1处会调用 CallbackInfo 的 ​​invokeCallbacks()​​。这个就是执行回调咯。 所以我们要搞清楚 CallbackInfo 是如何创建出来的。

下面这个 ​​createInfo()​​ 方法用来创建 CallbackInfo的:

private CallbackInfo createInfo(Class klass, @Nullable Method[] declaredMethods) { Class superclass = klass.getSuperclass(); Map handlerToEvent = new HashMap<>(); ... Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass); boolean hasLifecycleMethods = false; for (Method method : methods) { // 1 OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class); .... Lifecycle.Event event = annotation.value(); if (params.length > 1) { callType = CALL_TYPE_PROVIDER_WITH_EVENT; if (!params[1].isAssignableFrom(Lifecycle.Event.class)) { throw new IllegalArgumentException( "invalid parameter type. second arg must be an event"); } if (event != Lifecycle.Event.ON_ANY) { throw new IllegalArgumentException( "Second arg is supported only for ON_ANY value"); } } if (params.length > 2) { throw new IllegalArgumentException("cannot have more than 2 params"); } // 3 MethodReference methodReference = new MethodReference(callType, method); // 4 verifyAndPutHandler(handlerToEvent, methodReference, event, klass); } // 5 CallbackInfo info = new CallbackInfo(handlerToEvent); mCallbackMap.put(klass, info); mHasLifecycleMethods.put(klass, hasLifecycleMethods); return info; }

注释1: 遍历所有方法,获取其 ​​OnLifecycleEvent​​ 注解,这个注解正是实现 LifecycleObserver 接口时用到的。

注释2:获取该注解的值, 也就是在 @OnLifecycleEvent 中定义的事件

注释3: 创建一个 ​​MethodReference​​ 对象,其内部包括使用了该注解的方法。

注释4:用于将 ​​MethodReference​​ 和 对应的Event 存入到 Map类型的 handlerToEvent 中。

注释5: 新建 CallbackInfo, 并将 handlerToEvent 传进去。

继续来看 CallbackInfo 的 invokeCallbacks 方法:

static class CallbackInfo { final Map> mEventToHandlers; final Map mHandlerToEvent; CallbackInfo(Map handlerToEvent) { mHandlerToEvent = handlerToEvent; mEventToHandlers = new HashMap<>(); // 1 for (Map.Entry entry : handlerToEvent.entrySet()) { Lifecycle.Event event = entry.getValue(); List methodReferences = mEventToHandlers.get(event); if (methodReferences == null) { methodReferences = new ArrayList<>(); mEventToHandlers.put(event, methodReferences); } methodReferences.add(entry.getKey()); } } void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) { // 2 invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target); invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event, target); } private static void invokeMethodsForEvent(List 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); } } } }

注释1:对Map做一个类型转化,转化成HashMap

注释2: ​​invokeMthodsForEvent()​​​ 方法会传入 mEventToHandlers.get(event),也就是事件对应的 ​​MethodReference​​ 的集合。在 invokeMethodsForEvent 方法中,就回去遍历 MethodReference 的集合,调用 MethodReference 的 invokeCallback 方法,如下所示:

final class MethodReference { final int mCallType; final Method mMethod; void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) { try { 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; } } catch (InvocationTargetException e) { throw new RuntimeException("Failed to call observer method", e.getCause()); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } ...}

MethodReference 类中有两个变量,一个是callType,它代表调用方法的类型,另一个变量则是 Method,它代表方法,无论是哪种 callType 都会通过 invoke 对方法进行反射。

总结: 实现 LifecycleOvserver 接口的类中,注解修饰的方法和事件会被保存成一个 ​​​MethodReference​​,在生命周期变化的时候,会通过反射去调用这些对应生命周期的方法。

3.3 Lifecycle UML图

最后贴一下 UML图,更直观的了解他的一个架构(其实还是比较简单的):

参考文章

《Android进阶指北》第10章Android Jetpack架构组件​​​Android开发者–Lifecycle官方文档​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:微信等多家APP被点名!
下一篇:EventBus索引加速探究
相关文章

 发表评论

暂时没有评论,来抢沙发吧~