写点什么

【Android-Jetpack】Lifecycle- 从入门到精通

用户头像
Android架构
关注
发布于: 2021 年 11 月 07 日

super.onStop()myLocationListener.stop()}


}复制代码


androidx.lifecycle 软件包提供的类和接口可帮助您以弹性和隔离的方式解决这些问题。

基础使用

导入依赖

implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.0.0"复制代码

Lifecycle 使用

然后我们来看看怎么解决上面的问题?我们可以通过添加注解来监控组件的生命周期状态,您可以通过调用 Lifecycle 类的 addObserver()方法并传递观察者的实例来添加观察者,如以下示例中所示:


class MyObserver : LifecycleObserver {


@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)fun connectListener() {...}


@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)fun disconnectListener() {...}}


myLifecycleOwner.getLifecycle().addObserver(MyObserver())复制代码


LifecycleOwner 是单一方法接口,表示类具有 Lifecycle。它具有一种方法(即 getLifecycle(),该方法必须由类实现。此接口从各个类(如 FragmentAppCompatActivity)抽象化 Lifecycle 的所有权,并允许编写与这些类搭配使用的组件。任何自定义应用类均可实现 LifecycleOwner 接口。


实现 LifecycleObserver 的组件可与实现 LifecycleOwner 的组件完美配合,因为所有者可以提供生命周期,而观察者可以注册以观察生命周期。


class MyActivity : AppCompatActivity() {private lateinit var myLocationListener: MyLocationListener


override fun onCreate(...) {myLocationListener = MyLocationListener(this, lifecycle) { location ->// update UI}Util.checkUserStatus { result ->if (result) {myLocationListener.enable()}}}}复制代码


对于未知跟踪实例,我们可以让MyLocationListener 类实现 LifecycleObserver,然后在 onCreate 方法中实现 Activity 的 Lifecycle 对其进行初始化,然后配合注解。这意味着对生命周期状态的变化做出响应的逻辑会在MyLocationListener(而不是在 Activity)中进行声明。让各个组件存储自己的逻辑可使 Activity 和 Fragment 逻辑更易于管理


同时还要注意的是,如果 Lifecycle 现在未处于良好的状态,则应避免调用某些回调。例如,如果回调在 Activity 状态保存后运行 Fragment 事务,就会触发崩溃,因此我们绝不能调用该回调。为简化此使用场景,Lifecycle 类允许其他对象查询当前状态。


对应到 MyLocationListener 的做法如下:


internal class MyLocationListener(private val context: Context,private val lifecycle: Lifecycle,private val callback: (Location) -> Unit): LifecycleObserver {


private var enabled = false


@OnLifecycleEvent(Lifecycle.Event.ON_START)fun start() {if (enabled) {// connect}}


fun enable() {enabled = trueif (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {// connect if not connected}}


@OnLifecycleEvent(Lifecycle.Event.ON_STOP)fun stop() {// disconnect if connected}}复制代码


对于此实现,LocationListener 类可以完全感知生命周期。如果我们需要从另一个 Activity 或 Fragment 使用 LocationListener,只需对其进行初始化。所有设置和拆解操作都由类本身管理。


如果您尝试管理整个应用进程的生命周期,请参阅 ProcessLifecycleOwner

Applicaiton 生命周期 ProcessLifecycleOwner

通常我们判断在应用是不是处于前后台的做法是:注册一个 registerActivityLifecycleCallbacks(callback),然后在 callback 中利用一个全局变量做计数,在 onActivityStarted()中计数加 1,在 onActivityStopped 方法中计数减 1,从而判断前后台切换。


而使用 ProcessLifecycleOwner 可以直接获取应用前后台切换状态(记得先引入 lifecycle-process 依赖)。使用方式和 Activity 中类似,只不过要使用 ProcessLifecycleOwner.get() 获取 ProcessLifecycleOwner,代码如下:


public class MyApplication extends Application


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


{


@Overridepublic void onCreate() {super.onCreate();


//注册 App 生命周期观察者 ProcessLifecycleOwner.get().getLifecycle().addObserver(new ApplicationLifecycleObserver());}


/**


  • Application 生命周期观察,提供整个应用进程的生命周期

  • Lifecycle.Event.ON_CREATE 只会分发一次,Lifecycle.Event.ON_DESTROY 不会被分发。

  • 第一个 Activity 进入时,ProcessLifecycleOwner 将分派 Lifecycle.Event.ON_START, Lifecycle.Event.ON_RESUME。

  • 而 Lifecycle.Event.ON_PAUSE, Lifecycle.Event.ON_STOP,将在最后一个 Activit 退出后后延迟分发。如果由于配置更改而销毁并重新创建活动,则此延迟足以保证 ProcessLifecycleOwner 不会发送任何事件。

  • 作用:监听应用程序进入前台或后台*/private static class ApplicationLifecycleObserver implements LifecycleObserver {@OnLifecycleEvent(Lifecycle.Event.ON_START)private void onAppForeground() {Log.w(TAG, "ApplicationObserver: app moved to foreground");}


@OnLifecycleEvent(Lifecycle.Event.ON_STOP)private void onAppBackground() {Log.w(TAG, "ApplicationObserver: app moved to background");}}}复制代码

实现自定义 LifecycleOwner

支持库 26.1.0 及更高版本中的 Fragment 和 Activity 已实现 LifecycleOwner接口。如果你有一个自定义类并希望使其成为 LifecycleOwner,可以使用 LifecycleRegistry类,但需要将事件转发到该类,代码如下:


class MyActivity : Activity(), LifecycleOwner {


private lateinit var lifecycleRegistry: LifecycleRegistry


override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)


lifecycleRegistry = LifecycleRegistry(this)lifecycleRegistry.markState(Lifecycle.State.CREATED)}


public override fun onStart() {super.onStart()lifecycleRegistry.markState(Lifecycle.State.STARTED)}


override fun getLifecycle(): Lifecycle {return lifecycleRegistry}}复制代码


该 MainActivty 是实现了 Activity 类,而不是 AppcompatActivity(FragmentActivity) 类,所以需要这样的处理。我们来看看 FragmentActivity 中的源码,比如 onCreate方法和 onPause方法


public class FragmentActivity extends ComponentActivity implementsActivityCompat.OnRequestPermissionsResultCallback,ActivityCompat.RequestPermissionsRequestCodeValidator {


/**


  • A {@link Lifecycle} that is exactly nested outside of when the FragmentController

  • has its state changed, providing the proper nesting of Lifecycle callbacks

  • <p>

  • TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver*/final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this);


protected void onCreate(@Nullable Bundle savedInstanceState) {


···mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);···}


@Overrideprotected void onPause() {super.onPause();···mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);}}


//ComponentActivity.javapublic class ComponentActivity extends androidx.core.app.ComponentActivity implementsLifecycleOwner,ViewModelStoreOwner,SavedStateRegistryOwner,OnBackPressedDispatcherOwner {复制代码


明白了基本的操作,我们再看看看源码是如何实现的,注意,本文不会仔细深究源码,而是梳理一个大概的思路,如果想要讲具体深入每个细节,则可以照着我这个思路深入研究。

源码分析

Lifecycle 五种状态对应六个事件(生命周期)

首先我们来看 Lifecycle 这个类,让脑子里面有一个大致的概念


public abstract class Lifecycle {


/**


  • Lifecycle coroutines extensions stashes the CoroutineScope into this field.

  • @hide used by lifecycle-common-ktx*/@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)@NonNullAtomicReference<Object> mInternalScopeRef = new AtomicReference<>();// 添加观察者 @MainThreadpublic abstract void addObserver(@NonNull LifecycleObserver observer);// 移除观察者

  • @MainThreadpublic abstract void removeObserver(@NonNull LifecycleObserver observer);@MainThread@NonNullpublic abstract State getCurrentState(); // 获取当前状态,共五种状态


@SuppressWarnings("WeakerAccess")public enum Event { //对应六个生命周期方法,还多个一个 ON_ANY,可以响应任何事件 ON_CREATE,ON_START,ON_RESUME,ON_PAUSE,ON_STOP,ON_DESTROY,ON_ANY}


/**


  • Lifecycle states. You can consider the states as the nodes in a graph and

  • {@link Event}s as the edges between these nodes.*/@SuppressWarnings("WeakerAccess")public enum State { //五种状态,对应生命周期的方法/Event 方法 DESTROYED,INITIALIZED,CREATED,STARTED,RESUMED;public boolean isAtLeast(@NonNull State state) {return compareTo(state) >= 0;}}}复制代码


如果你觉得还不够清楚,只需要要记住五种状态对应六个生命周期方法(六个事件,ON_ANY 可以忽略)。然后我们再来看看官方的图,五个状态对应六个生命周期方法,六个事件,这句话一定要记住。



Event 表示生命周期事件,与 Activity/Fragment 生命周期方法对应。State 是 Lifecycle 这些生命周期对应的状态,为什么不直接用对应的生命周期设置对应的状态呢,而是设置了五个状态呢?原因很简单,因为 Lifecycle 不仅仅只是给自己用这些状态,还有 LiveData,ViewMode 等控件也会用到这些状态的进行逻辑判断,所以 Google 工程师做了更好的封装和管理。


//Lifecycle.class


  • {@link Event#ON_CREATE}, {@link Event#ON_START}, {@link Event#ON_RESUME} events in this class

  • are dispatched <b>after</b> the {@link LifecycleOwner}'s related method returns.

  • {@link Event#ON_PAUSE}, {@link Event#ON_STOP}, {@link Event#ON_DESTROY} events in this class

  • are dispatched <b>before</b> the {@link LifecycleOwner}'s related method is called.复制代码


Event 中的 ON_CREATE,ON_START,ON_RESUME 是在 LifecyclerOwner 对应的方法执行之后分发,ON_PAUSE,ON_STOP,ON_DESTROY 是在 LifecyclerOwner 对应的方法执行之前分发。


我们的 Activity 因为实现了 LifecycleOwner 才能直接调用 getLifecycle(),从前面的分析我们可以看到是在 ComponentActivity 中实现了该接口


public class ComponentActivity extends androidx.core.app.ComponentActivity implementsLifecycleOwner,ViewModelStoreOwner,SavedStateRegistryOwner,OnBackPressedDispatcherOwner {private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);mSavedStateRegistryController.performRestore(savedInstanceState);ReportFragment.injectIfNeededIn(this);if (mContentLayoutId != 0) {setContentView(mContentLayoutId);}}


@NonNull@Overridepublic Lifecycle getLifecycle() {return mLifecycleRegistry;}// LifecycleRegistry.javapublic class LifecycleRegistry extends Lifecycle {


复制代码


getLifecycle().addObserver(MyObserver()) 是我们添加观察者的方式,我们来看看addObserver方法的实现,因为的实现是LifecycleRegistry


//LifecycleRegistry.java@Overridepublic void addObserver(@NonNull LifecycleObserver observer) {State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;//带状态的观察者,这个状态的作用:新的事件触发后 遍历通知所有观察者时,判断是否已经通知这个观察者了 ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);


if (previous != null) {return;}LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {// it is null we should be destroyed. Fallback quicklyreturn;}//下面代码的逻辑:通过 while 循环,把新的观察者的状态 连续地 同步到最新状态 mState。//意思就是:虽然可能添加的晚,但把之前的事件一个个分发给你(upEvent 方法),即粘性 boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;State targetState = calculateTargetState(observer);mAddingObserverCounter++;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 recalculatetargetState = calculateTargetState(observer);}


if (!isReentrance) {// we do sync only on the top level.sync();}mAddingObserverCounter--;}复制代码


通过statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));分发事件,我们先来看ObserverWithState


static 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 = getStateAfter(event);mState = min(mState, newState);mLifecycleObserver.onStateChanged(owner, event);mState = newState;}复制代码


mLifecycleObserver的值为Lifecycling.lifecycleEventObserver(observer);,然后查看方法lifecycleEventObserver


@NonNullstatic LifecycleEventObserver lifecycleEventObserver(Object object) {boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;···return new ReflectiveGenericLifecycleObserver(object);}复制代码


查看最后一行中的ReflectiveGenericLifecycleObserver


class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {private final Object mWrapped;private final CallbackInfo mInfo;


ReflectiveGenericLifecycleObserver(Object wrapped) {mWrapped = wrapped;mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass()); //存放了注解方法的信息}


@Overridepublic void onStateChanged(LifecycleOwner source, Event event) {mInfo.invokeCallbacks(source, event, mWrapped); //执行状态变化对应的方法}}复制代码


getInfo的内容如下:


CallbackInfo getInfo(Class klass) {CallbackInfo existing = mCallbackMap.get(klass);if (existing != null) {return existing;}existing = createInfo(klass, null);return existing;}复制代码

处理注解

接下来是重要方法createInfo,在该方法中进行注解的处理,并存储到 mCallbackMap。提供给后面的观察者调用


//createInfo,遍历方法 处理注解,将 private CallbackInfo createInfo(Class klass, @Nullable Method[] declaredMethods) {Class superclass = klass.getSuperclass();Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>();if (superclass != null) {CallbackInfo superInfo = getInfo(superclass);if (superInfo != null) {handlerToEvent.putAll(superInfo.mHandlerToEvent);}}


Class[] interfaces = klass.getInterfaces();for (Class intrfc : interfaces) {for (Map.Entry<MethodReference, Lifecycle.Event> entry : getInfo(intrfc).mHandlerToEvent.entrySet()) {verifyAndPutHandler(handlerToEvent, entry.getKey(), entry.getValue(), klass);}}


Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);boolean hasLifecycleMethods = false;for (Method method : methods) {OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);if (annotation == null) {continue;}hasLifecycleMethods = true;Class<?>[] params = method.getParameterTypes();int callType = CALL_TYPE_NO_ARG;if (params.length > 0) {callType = CALL_TYPE_PROVIDER;if (!params[0].isAssignableFrom(LifecycleOwner.class)) {throw new IllegalArgumentException("invalid parameter type. Must be one and instanceof LifecycleOwner");}}Lifecycle.Event event = annotation.value();


···MethodReference methodReference = new MethodReference(callType, method);verifyAndPutHandler(handlerToEvent, methodReference, event, klass);}CallbackInfo info = new CallbackInfo(handlerToEvent);mCallbackMap.put(klass, info);mHasLifecycleMethods.put(klass, hasLifecycleMethods);return info;}复制代码

被观察者通知观察者

观察者进行回调的时候调用了ReflectiveGenericLifecycleObservermInfo.invokeCallbacks(source, event, mWrapped);,最终会调用到MethodReferenceinvokeCallback方法。


void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {//noinspection TryWithIdenticalCatchestry {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);}}复制代码


到这里观察者的注册和注解的处理,以及通知被观察者的流程就已经分析完毕了。

如何监听生命周期

我们回到之前的ComponentActivityonCreate方法中可以看到调用了ReportFragment.injectIfNeededIn(this);,这个 ReportFragment 和 Glide 中使用透明的 Fragment 获取界面生命周期是一样的。


public static void injectIfNeededIn(Activity activity) {// ProcessLifecycleOwner should always correctly work and some activities may not extend// FragmentActivity from support lib, so we use framework fragments for activitiesandroid.app.FragmentManager manager = activity.getFragmentManager();if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();// Hopefully, we are the first to make a transaction.

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
【Android-Jetpack】Lifecycle-从入门到精通