感谢大家和我一起,在Android世界打怪升级!

Jetpack系列的第一篇文章,以Lifecycle作为起点,其重要性不言而喻。本篇文章会从使用到原理依次进阶,由浅入深的剖析Lifecycle。

一、Jetpack是什么

安卓开发者官网对Jetpack的介绍:

Jetpack 是一个由多个库组成的套件,可帮助开发者遵循最佳做法、减少样板代码并编写可在各种 Android版本和设备中一致运行的代码,让开发者可将精力集中于真正重要的编码工作。

简单来说就是很多官方封装的提升开发效率的库。从官网摆放的位置足以看出对Jetpack的重视程度。

二、Lifecycle是什么

构建生命周期感知型组件,这些组件可以根据 Activity 或 Fragment 的当前生命周期状态调整行为。

简单叙述下原理:使用了观察者模式,Activity与Fragment拥有生命周期感知的能力,作为被观察者,可向其内部注册观察者,在生命周期变化时通知所有观察者。

三、Lifecycle的使用

使用分为两步:①创建观察者②注册观察者。被观察者已经被Android源码实现了。

3.1 创建观察者

1、创建类实现LifecycleObserver接口。

2、在其内部创建方法(方法名随意),参数可填LifecycleOwner,也可不填。

3、给方法加注解 @OnLifecycleEvent(Lifecycle.Event.XXX) ,可以让该方法监听到注解生命周期的变化。

4、下面代码罗列了所有Lifecycle.Event枚举,Lifecycle.Event.ON_ANY 可以监听所有其他生命周期变化。

// 1、创建类实现LifecycleObserver接口
public class TestLifecycleObserver implements LifecycleObserver {private static final String TAG = "TestLifecycleObserver";@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)// 2、在其内部创建方法(方法名随意),参数可填LifecycleOwner,也可不填。void onCreate(LifecycleOwner owner) {Log.e(TAG, "========onCreate====" + owner);}// 3、给方法加注解 @OnLifecycleEvent(Lifecycle.Event.XXX) // 可以让该方法监听到注解生命周期的变化。@OnLifecycleEvent(Lifecycle.Event.ON_START)void onStart() {Log.e(TAG, "========onStart");}@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)void onResume(LifecycleOwner owner) {Log.e(TAG, "========onResume");}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)void onPause(LifecycleOwner owner) {Log.e(TAG, "========onPause");}@OnLifecycleEvent(Lifecycle.Event.ON_STOP)void onStop(LifecycleOwner owner) {Log.e(TAG, "========onStop");}@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)void onDestroy(LifecycleOwner owner) {Log.e(TAG, "========onDestroy");}// Lifecycle.Event.ON_ANY 可以监听所有生命周期变化@OnLifecycleEvent(Lifecycle.Event.ON_ANY)void onAny(LifecycleOwner owner) {Log.e(TAG, "========onAny");}
}

3.2 注册观察者

AppCompatActivity与Fragment是默认的被观察者,在其内部通过调用getLifecycle().addObserver(观察者)注册定义好的观察者即可。

// AppCompatActivity内部实现了被观察者
public class TestLifecycleActivity extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_lifecycle);// 注册观察者getLifecycle().addObserver(new TestLifecycleObserver());}
}
// Fragment内部实现了被观察者
public class TestLifecycleFragment extends Fragment {@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 注册观察者getLifecycle().addObserver(new TestLifecycleObserver());}
}

四、Lifecycle原理

如上所述,Lifecycle的原理是观察者模式。

4.1 两个接口

观察者模式涉及到被观察者和观察者,所以先介绍两个接口,LifecycleOwner与LifecycleObserver。

1、 LifecycleOwner对应被观察者

2、LifecycleObserver对应观察者

4.2 被观察者

在【3.1 创建观察者】章节,已经知道LifecycleObserver是我们创建的观察者类去实现该接口。那被观察者的LifecycleOwner是在哪里被实现的呢?

细心的朋友已经发现了,在【3.2 注册观察者】章节的第一句,提到了AppCompatActivity与Fragment是默认的被观察者,那就是说这两个类应该是被谷歌工程师实现了LifecycleOwner接口。



果不其然!上面两个类确实是实现了LifecycleOwner接口,作为默认的被观察者。

【阶段小结】
Activity与Fragment拥有生命周期感知的能力,所以将其设置为生命周期的被观察者更合适不过,在其内部默认实现了LifecycleOwner接口。

我们可以通过创建观察者类实现LifecycleObserver接口来注册到被观察者(Activity与Fragment)中。等待生命周期发生变化,被观察者回调所有注册在内部的观察者,通知相应的注解生命周期方法。

所以整个流程其实也分为两个阶段:①注册观察者 ②通知观察者

4.3 注册观察者

咱们以Activity的注册观察者方法为起点去梳理注册流程,源码阶段我会一行一行的和大家一起梳理,不重要会直接略过。

4.3.1 getLifecycle

首先咱们看看getLifecycle()方法返回了什么?

如上所示,getLifecycle()方法返回的是一个LifecycleRegistry对象,registry是注册处的意思,那咱们盲猜这个类是生命周期观察者的注册处,下面来验证一下。


一进入该类,可以看到LifecycleRegistry是继承自Lifecycle抽象类,Lifecycle抽象类里面定义了一些模版方法和生命周期状态。

另一方面,这个类里面的几个属性引起了我的注意

1、mObserverMap: 难道这就是保存观察者的地方?该Map还以观察者LifecycleObserver为key,难道这个Map不仅能保存观察者,还能让一个观察者对象只存在一个?

2、mState: 当前所处于的生命周期状态,这个State是一个枚举,在Lifecycle类中有定义,枚举如下,和生命周期onCreate()、onResume()有些类似,但是生命周期是一个点,而State代表的是达到这个生命周期之后的一种状态,所以英文以ED结尾表示完成式

public enum State {DESTROYED,INITIALIZED,CREATED,STARTED,RESUMED;public boolean isAtLeast(@NonNull State state) {return compareTo(state) >= 0;}
}

3、mLifecycleOwner: 对Activity的弱引用包装了。

【阶段小结】
getLifecycle()方法返回的是LifecycleRegistry对象,目前猜想是一个生命周期观察者的注册处,里面使用Map将观察者进行,并且保存了当前生命周期的状态。

4.3.2 addObserver上半段

再回到这个注册方法,咱们继续看addObserver方法,看这个自定义观察者到底被注册到了哪里。

在LifecycleRegistry中我们找到了这个方法,因为太长咱们分段来看,文章以主要代码为主,不重要的一笔带过。

// 根据变量判断是否强制在主线程执行该方法
// 在LifecycleRegistry初始化时默认强制在主线程执行
// 所以如果不在主线程执行该方法会抛异常。
enforceMainThreadIfNeeded("addObserver");
// 给当前Observer指定一个初始State
// 该State要区别于LifecycleOwner的State
// LifecycleOwner的State是当前被观察者的状态
// 当前Observer的State是用于判断是否被观察者的State一致
// 默认初始为INITIALIZED或DESTROYED
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// 将Observer与初始化State封装到了同一个类中,让监听者和状态绑定
// ObserverWithState类的源码在文章下面
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 将Observer保存进入Map!
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {return;
}// putIfAbsent源码
@Override
public V putIfAbsent(@NonNull K key, @NonNull V v) {Entry<K, V> current = get(key);// 如果之前该观察者对象被保存过if (current != null) {// 就直接返回之前保存的valuereturn current.mValue;}// 如果没被保存过就保存并返回nullmHashMap.put(key, put(key, v));return null;
}

这段终于到我们想看的代码了!!!

这就是将观察者作为key,将上面封装了状态的观察者作为value保存到Map中啊!!咱们之前猜想的mObserverMap真的是保存所有监听者的地方!!

如果putIfAbsent方法返回不为null,就说明该Observer已经被注册过了,不能再次注册。

【阶段小结】
到这里,Observer已经成功被注册了,Observer作为key,ObserverWithState(被封装了状态的Observer)作为value,保存到了mObserverMap中,并且不能重复注册。

4.3.3 addObserver下半段

接下来挑重点看addObserver方法的下半段:

// 有轻微删减,有兴趣可以看下源码
State targetState = calculateTargetState(observer);
while ((statefulObserver.mState.compareTo(targetState) < 0&& mObserverMap.contains(observer))) {final Event event = Event.upFrom(statefulObserver.mState);if (event == null) {throw new IllegalStateException("no event up from " + statefulObserver.mState);}statefulObserver.dispatchEvent(lifecycleOwner, event);// mState / subling may have been changed recalculatetargetState = calculateTargetState(observer);
}

总体来说,这段代码就是将上半段状态为INITIALIZED的观察者同步到和被观察者相同的状态。

// 根据计算获取一个要前往的目标状态
State targetState = calculateTargetState(observer);// calculateTargetState方法源码
// 使用当前观察者的上一个状态、被观察者的当前状态、父容器的当前状态去比较最小值
private State calculateTargetState(LifecycleObserver observer) {Map.Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);State siblingState = previous != null ? previous.getValue().mState : null;State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1): null;return min(min(mState, siblingState), parentState);
}
【小知识】枚举是谁放在前面谁小
// 循环 直到观察者的State是和targetState一致
while ((statefulObserver.mState.compareTo(targetState) < 0&& mObserverMap.contains(observer))) {...
}

循环的第一行又引出了一个Event类,这个类和State有些相似,State是用来表明一种状态,Event是用来描述一个事件。

public enum Event {ON_CREATE,ON_START,ON_RESUME,ON_PAUSE,ON_STOP,ON_DESTROY,ON_ANY;public static Event downFrom(@NonNull State state) {}public static Event downTo(@NonNull State state) {}public static Event upFrom(@NonNull State state) {}public static Event upTo(@NonNull State state) {}public State getTargetState() {}
}

通过Event事件到达State状态,比如通过ON_CREATE的Event,可以到达CREATED的State。

State和Event之间的相互转换关系如下图:

// 将State进行状态上升,将上升所需要的Event返回,参考上图
public static Event upFrom(@NonNull State state) {switch (state) {// 从INITIALIZED状态上升,会返回ON_CREATE事件case INITIALIZED:return ON_CREATE;// 从CREATED状态上升,会返回ON_START事件case CREATED:return ON_START;case STARTED:return ON_RESUME;default:return null;}
}
// 通过Event,调用对应的观察者方法,更新自身的State状态
statefulObserver.dispatchEvent(lifecycleOwner, event);// 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 = event.getTargetState();mState = min(mState, newState);// 根据Event通知观察值(Observer)调用相应的方法mLifecycleObserver.onStateChanged(owner, event);// 更新自身的State状态mState = newState;}
}

【阶段小结】
到此,执行完了while循环,这个新的Observer的状态已经更新到与LifecyclerOwner完全一致了。

4.3.4 总结

1、通过getLifecycle()方法拿到LifecycleRegistry(生命周期注册处)。

2、将创建的观察者通过addObserver方法注册到LifecycleRegistry内部的Map中,key是观察者,value是封装了状态的观察者。且不能重复注册。

3、注册的观察者还会和LifecycleOwner的状态进行同步,并调用对应的观察者方法。

4.4 通知观察者

其实了解注册观察者流程后,我们大概可以猜想出被观察者如何通知观察者。咱们先来推论一下,Activity和Fragment应该是在感知到生命周期变化之后,从LifecycleRegistry(生命周期注册处)获取所有观察者并进行状态同步的。

4.4.1 Fragment通知观察者

Fragment中也有LifecycleRegistry,所以咱们看一下调用的位置,可以发现performCreate、performStart等方法都会有handleLifecycleEvent方法的调用!其实走到这一步就是开始通知观察者了,具体逻辑后面再看,以performStart为例看下:

void performStart() {mChildFragmentManager.noteStateNotSaved();mChildFragmentManager.execPendingActions(true);mState = STARTED;mCalled = false;onStart();if (!mCalled) {throw new SuperNotCalledException("Fragment " + this+ " did not call through to super.onStart()");}// 处理Lifecycle.Event.ON_START事件// 最终调用观察者对应方法mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);if (mView != null) {mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);}mChildFragmentManager.dispatchStart();
}

【阶段小结】
Fragment就是在自己能感知生命周期方法的内部去通知观察者变更状态的。

4.4.2 Activity通知观察者

在ComponentActivity的onCreate方法中可以找到一句ReportFragment.injectIfNeededIn(this),咱们看看里面做了什么

首先这个ReportFragment没有页面,会偷偷绑定到Activity上,能感知生命周期变化。另一方面通知观察者的方式在 SDK_INT >= 29 以后进行了变更,咱们分为两段看。

SDK_INT < 29

我们先来看下ReportFragment的生命周期方法

@Override
public void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);dispatchCreate(mProcessListener);// 熟悉的身影dispatch(Lifecycle.Event.ON_CREATE);
}@Override
public void onStart() {super.onStart();dispatchStart(mProcessListener);dispatch(Lifecycle.Event.ON_START);
}@Override
public void onResume() {super.onResume();dispatchResume(mProcessListener);dispatch(Lifecycle.Event.ON_RESUME);
}

这里我们看到了熟悉的Lifecycle.Event身影,所以咱们继续看下dispatch方法做了什么

private void dispatch(@NonNull Lifecycle.Event event) {if (Build.VERSION.SDK_INT < 29) {// Only dispatch events from ReportFragment on API levels prior// to API 29. On API 29+, this is handled by the ActivityLifecycleCallbacks// added in ReportFragment.injectIfNeededIndispatch(getActivity(), event);}
}static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {if (activity instanceof LifecycleRegistryOwner) {// 通知观察者((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);return;}if (activity instanceof LifecycleOwner) {Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();if (lifecycle instanceof LifecycleRegistry) {// 通知观察者((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);}}
}

很明显这个方法只能在SDK_INT < 29的时候才能生效,最终我们都能看到handleLifecycleEvent方法的调用!和Fragment如出一辙。

【阶段小结】
Activity通知观察者会偷偷注册一个无布局ReportFragment,在SDK_INT < 29时ReportFragment直接根据生命周期方法去通知观察者变更状态。

SDK_INT >= 29

再看这个图,在SDK_INT >= 29时执行了一句代码,咱们看一下

看到这个LifecycleCallbacks类,一切都明朗了!!该类继承自Application.ActivityLifecycleCallbacks,注册到Activity中即可响应Activity的生命周期变化。registerIn方法直接将这个回调类注册到了Activity中,从最开始使用Fragment的生命周期转型为直接使用Activity的生命周期变化!

【阶段小结】
Activity通知观察者会偷偷注册一个无布局ReportFragment,在SDK_INT >= 29时ReportFragment会给Activity注册一个生命周期监听,直接监听Activity的生命周期变化,调用dispatch双参数方法,通知观察者变化状态。

4.4.3 handleLifecycleEvent

Activity和Fragment的分发我们只最后停留在handleLifecycleEvent方法上,现在进行一下简单的流程代码分析。

handleLifecycleEvent —— moveToState —— sync —— backwardPass / forwardPass —— observer.dispatchEvent

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {enforceMainThreadIfNeeded("handleLifecycleEvent");moveToState(event.getTargetState());
}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();if (lifecycleOwner == null) {throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"+ "garbage collected. It is too late to change lifecycle state.");}while (!isSynced()) {mNewEventOccurred = false;// no need to check eldest for nullability, because isSynced does it for us.if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {backwardPass(lifecycleOwner);}Map.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<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =mObserverMap.iteratorWithAdditions();while (ascendingIterator.hasNext() && !mNewEventOccurred) {Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred&& mObserverMap.contains(entry.getKey()))) {pushParentState(observer.mState);final Event event = Event.upFrom(observer.mState);if (event == null) {throw new IllegalStateException("no event up from " + observer.mState);}observer.dispatchEvent(lifecycleOwner, event);popParentState();}}
}

上面的流程就是通知观察者的逻辑,无非是判断状态向前走还是向后走,最终都调用了observer的dispatchEvent方法,里面会根据Event事件去调用观察者注册的事件。

总结

最后咱们再总结一下Lifecycle的原理:

  1. 观察者模式:LifecycleOwner(被观察者)、LifecycleObserver(观察者),AppCompatActivity与Fragment默认实现了LifecycleOwner接口。
  2. 注册观察者:AppCompatActivity与Fragment中都有LifecycleRegistry(生命周期注册处),创建的观察者通过addObserver方法注册到LifecycleRegistry内部的Map中,赋予初始State,不能重复注册,还会和LifecycleOwner的状态进行同步,并调用对应的观察者方法。
  3. 通知观察者:Fragment通过自己的生命周期变化通知观察者,Activity则偷偷注册了ReportFragment,在SDK_INT < 29 时使用ReportFragment的生命周期变化通知观察者,在SDK_INT >= 29时则在Activity中注册了生命周期监听回调通知观察者。

这样Lifecycle的介绍就结束了,希望大家读完这篇文章,会对Lifecycle有一个更深入的了解。如果我的文章能给大家带来一点点的福利,那在下就足够开心了。

下次再见!

Lifecycle是什么?相关推荐

  1. Spring Boot项目错误:Error parsing lifecycle processing instructions

    pom.xml文件错误:Error parsing lifecycle processing instructions 解决方法:清空.m2/repository下的所有依赖文件,重新下载即可解决该问 ...

  2. React文档 state and lifecycle

    状态和生命周期 这篇介绍 React 组件中状态和声明周期的概念.详情可以查看API参考 . 思考前一部分中时钟的例子.渲染元素中,我们仅学习了一种更新 UI 的方式.调用 ReactDOM.rend ...

  3. 好记性不如烂笔杆-android学习笔记二 Acitvity lifecycle 生命周期

    7,//Acitvity lifecycle 生命周期 /** *1,一个Activity就是一个类,并且这个类要继承Activity *2,复写onCreate方法 *3,每个Activity需要在 ...

  4. Spring中SmartLifecycle和Lifecycle的作用和区别

    欢迎关注方志朋的博客,回复"666"获面试宝典 本文基于SpringBoot 2.5.0-M2讲解Spring中Lifecycle和SmartLifecycle的作用和区别,以及如 ...

  5. Maven:No goals have been specified for this build. You must specify a valid lifecycle phase

    1. 执行打包命令报错: No goals have been specified for this build. You must specify a valid lifecycle phase o ...

  6. Lifecycle Activity和Fragment生命周期感知组件 LifecycleObserver MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. Unknown lifecycle phase mvn

    Unknown lifecycle phase "mvn" maven执行命令错误  : 执行输入命令即可,不需要添加 mvn 此处不需要写mvn,而是执行写compile就行,否 ...

  8. Android JetPack Lifecycle源码解析

    是什么? JetPack Lifecycle是一个页面(Activity/Fragment)生命周期的组件,当你想监听生命周期,那么就可以使用这个组件. 怎么用? 第一种: getLifecycle( ...

  9. Android Jetpack 组件之 Lifecycle源码

    1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面. A ...

  10. Android Jetpack 组件之 Lifecycle使用

    1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面. A ...

最新文章

  1. vconsole插件_移动端调试面板插件vconsole
  2. Android JNI和NDK学习(5)--JNI分析API
  3. 硬件基础:电脑当中各个硬件的作用介绍
  4. 串口MSComm控件五种不同校验方式对数据收发的影响
  5. 狗窝里的小日子- 4 ...
  6. DataGridView控件
  7. uniapp手写_【转】uni-app框架纯手写微信小程序开发左侧滑动菜单
  8. 第八章 交互技术,8.5 双11晚会背后的技术(作者:邵雍)
  9. Hibernate异常归总
  10. atitit.跨架构 bs cs解决方案. 自定义web服务器的实现方案 java .net jetty  HttpListener
  11. k8s拉取harbor镜像_Kubernetes-连接Harbor仓库拉取镜像
  12. 微信小程序开发前端基础知识
  13. 怎么引流推广?10种有效引流吸粉方法
  14. Chrome上关于微信网页版WeChat不能正常登录的解决方案
  15. laydate-v5.0.9自定义小时范围和分钟间隔(半小时)
  16. python人机对战_【人机对战】用python打造经典井字游戏
  17. 基于姿态估计的运动计数APP开发
  18. greasyfork脚本怎么取消_greasy fork怎么安装脚本 greasy fork脚本安装教程-站长资讯中心...
  19. 读后感:李敖先生北大演讲
  20. css实现礼券效果2

热门文章

  1. python经典类和新式类_python中经典类和新式类的区别
  2. 基于paddlepaddle构建resnet神经网络的蝴蝶分类
  3. 基金业务中常见费用知识
  4. 基于Java+SpringMVC+Mybaties+jsp+layui实现的宿舍管理系统设计与实现
  5. 批量删除某网站上传的题库
  6. 教你怎么制作高大上的三维热力图
  7. barrier linux,Linux Barrier I/O 实现分析笔记
  8. Linux基础,系统概叙与虚拟机搭建+CentOS系统安装(建议收藏)
  9. 4. 卷积神经网络CNN
  10. mac安装adb报错Unknown command: cask