前言:写作就跟生活一样,是一趟发现之旅。
在早期 Andorid 架构中,生命周期的事件监听和状态查询,我们需要自定义一套提供侦测功能的 Activity/Fragment 基类及回调接口,在 Activity/Fragment 的生命周期方法中实现依赖组件的操作,在外部进行事件监听和状态查询。这种模式会导致代码条理性很差而且会扩散错误。
在 Lifecycle
引入后,可以避免在 Activity/Fragment 生命周期方法内写太多的业务逻辑处理代码,这样可以使我们的业务逻辑更加解耦。有助于您编写出更有条理且往往更精简的代码,此类代码更易于维护。
Lifecycle
是一个具备宿主生命周期感知能力的组件。它持有组件(Activity/Fragment)生命周期状态信息,并且允许其观察者监听宿主生命周期状态变化。
在 build.gradle
文件中添加依赖:
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1"
implementation "androidx.lifecycle:lifecycle-common:2.5.1"
使用 Lifecycle
观察宿主状态有三种实现方式。
第一种是实现 LifecycleObserver
接口,采用注解方式,使用 @OnLifecycleEvent
标记自定义的方法以实现回调。
//1.自定义LifecycleObserver观察者,用注解声明每个方法观察宿主的状态
public class MyLifecycleObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onStart(@NotNull LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onStop(@NotNull LifecycleOwner owner) {
}
}
//2.宿主中注册观察者,观察宿主生命周期状态变化
class MyFragment extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyLifecycleObserver observer = new MyLifecycleObserver();
getLifecycle().addObserver(observer);
}
}
实现 LifecycleObserver
接口,只需要在指定方法上面标记注解,来观察宿主的生命周期,注解里面标记着生命周期事件类型就可以了。然后在宿主注册这个 LifecycleObserver
,它不需要销毁的时候进行反注册。
第二种方式:定义一个类,实现 DefaultLifecycleObserver
接口,里面提供了完整的生命周期事件,为所有的生命周期事件都定义了对应的回调方法。它实现了 FullLifecycleObserver
接口,使用了 default 关键字空实现了各个方法。
class MyFullLifeObserver : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {}
override fun onStart(owner: LifecycleOwner) {}
override fun onResume(owner: LifecycleOwner) {}
override fun onPause(owner: LifecycleOwner) {}
override fun onStop(owner: LifecycleOwner) {}
override fun onDestroy(owner: LifecycleOwner) {}
}
使用 DefaultLifecycleObserver
后,就需要把注解实现相关逻辑移除。即使保留注解,由于 Lifecycling
的处理逻辑(系统架构逻辑中所有传入的观察者都会经过 Lifecycling
处理,下面会讲解到),任何 FullLifecycleObserver
的实现类 (即包括DefaultLifecycleObserver
) 内部所有的 @OnLifecycleEvent
注解都会失效。
第三种方式:实现 LifecycleEventObserver
,它是 LifecycleObserver
的子接口。只有一个 onStateChanged
方法,以 Lifecycle.Event
入参提供事件区分的形式,进行统一方法回调。
interface LifecycleEventObserver : LifecycleObserver {
// 宿主生命周期变化的事件都会通知到这个方法
fun onStateChanged(owner: LifecycleOwner?, event: Lifecycle.Event?)
}
//继承自LifecycleEventObserver,复写onStateChanged方法
class MyLifecycleEventObserver : LifecycleEventObserver {
override fun onStateChanged(owner: LifecycleOwner?, event: Lifecycle.Event?) {
//需要自行判断Event是onStart还是onStop
}
}
无论哪一种方法都需要在宿主中注册观察者。推荐使用第二种和第三种方式,第一种不推荐使用。
为下面更好深入理解原理,我们先来简单了解下 Lifecycle
组件中几个重要的类:
Lifecycle(生命周期) :一个核心抽象类,用于存储有关组件(如 activity/fragment 的生命周期状态的信息,并允许其他对象观察此状态。继承该类的子类,表示本身是一个 具有Android生命周期特性 的对象。
LifecycleOwner:核心接口,Lifecycle
持有者,该接口的实现类表示能够为外部提供Lifecycle
实例。具有 Android 生命周期的类。这些事件可以被自定义组件用来处理生命周期的变化,而不需要在 Activity/Fragment 中实现任何代码。
LifecycleRegistry:核心类,Lifecycle
的实现类,可以处理多个观察者。实现 Lifecycle
定义生命周期观察订阅,生命周期查询的方法。还实现了架构中,生命周期变化时触发的自身状态处理和相关对观察者的订阅回调的逻辑。
LifecycleObserver:观察者,将一个类标记为生命周期观察者。实现该接口的类,通过注解的方式,可以通过被 LifecycleOwner
类的 addObserver()
方法注册,LifecycleObserver
便可以观察到 LifecycleOwner
的生命周期事件。
State :当前生命周期所处的状态。
Event :当前生命周期改变对应的事件。从框架和 Lifecycle
类分派的生命周期事件。这些事件对应到 activity/fragment 中的回调事件。
LifecyclerOwner、Lifecycle、LifecyleRegistry 和 Observer 的关系如下图:
一般来说宿主代表着 Activity/Fragment,都实现了 LifecyclerOwner
接口;那么每个宿主必须复写 getLifecycle()
,并且返回一个 Lifecycle
对象,这个 Lifecycle
对象实际上是LifecycleRegistry
,只不过它采用的是面向接口的编程方式,我们对 LifecycleRegistry
注册 Observer
的时候,可以是 LifecycleObserver
,FullLifecyclerOberver
,LifecyclerEventObserver
。
系统框架中,LifecycleOwner
接口的实现类为 ComponentActivity
和 Fragment
,两者提供的 Lifecycle
对象,是系统框架实现中 Lifecycle
的唯一子类 LifecycleRegistry
。
public class Fragment implements LifecycleOwner {
// 创建LifecycleRegistry 并且把this传递进去
LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
public Lifecycle getLifecycle() {
//2.复写自LifecycleOwner,所以必须new LifecycleRegistry对象返回
return mLifecycleRegistry;
}
//······
}
Fragment 内 Lifecycle
核心代码片段,实现了 LifecycleOwner
接口,它表示生命周期宿主,持有生命周期(Lifecycle对象),该接口的生命周期的改变会被其注册的观察者 LifecycleObserver
观察到并触发其对应的事件。
必须复写 getLifecycle()
这个方法,返回的实际是 mLifecycleRegistry
,说明 Lifecycle
是 LifecycleRegistry
的父类,这是一种面向接口的编程思想。
public class Fragment implements LifecycleOwner {
//······
void performCreate(Bundle savedInstanceState) {
//······
onCreate(savedInstanceState);
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
void performStart() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
void performResume() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}
void performPause() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
void performStop() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}
void performDestroy() {
mChildFragmentManager.dispatchDestroy();
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
//······
}
}
我们注册 Lifecycle
的时候,实际上都注册到 LifecycleRegistry
里面去了。通过 handleLifecycleEvent()
分发自己的状态到每个观察者,从而实现观察生命周期实现变化的能力。看起来简单实际上 Lifecycle
在分发生命周期的时候并不简单,所有逻辑重点都在 LifecycleRegistry
。
Fragment 是如何派发生命周期的?也就是它会在自己生命周期里面,让 LifecycleRegistry
去分发生命周期事件,给每一个观察者。但是 Activity 中并不是这么做的。
Activity 实现 Lifecycle
的核心源码,需要来到 ComponentActivity
里面,同样也是实现了 LifecycleOwner
接口:
public class ComponentActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
//复写getLifecycle(),返回LifecycleRegistry对象
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//往Activity上添加一个fragment,用以报告生命周期的变化
//目的是为了兼顾不是继承自AppCompactActivity的场景
ReportFragment.injectIfNeededIn(this);
}
}
与上面 Fragment 的实现类似,它实现了 LifecycleOwner
,表示一个生命周期的宿主,必须实现 getLifecycle()
方法,返回一个 Lifecycle
,也就是 LifecycleRegistry
。
但是在 ComponentActivity
里面并没有在它的每个生命周期方法里面把它的状态分发给一个观察者,但是在 onCreate()
方法里面调用 ReportFragment.injectIfNeededIn(this)
这种做法实际上是往自己里面添加了一个不可见的 Fragment,专门用于报告分发给每个观察者。
public class ReportFragment extends Fragment {
public static void injectIfNeededIn (Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
// API 29 以上可以直接注册正确的生命周期回调
activity.registerActivityLifecycleCallbacks(
new LifecycleCallbacks ()
);
}
// 兼容API 29之前的,需要支持直接继承Activity的,使用Fragment来正确获得生命周期事件
android.app.FragmentManager manager = activity . getFragmentManager ();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment (), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
}
所以 Activity 事件的分发是依靠 ReportFragment
来完成的。
ReportFragment
将自身添加到 Activity 中实现。ActivityLifecycleCallbacks
的相关方法,可以直接通过注册 ActivityLifecycleCallbacks
观察生命周期。ComponentActivity
为什么这么做而不直接在 Activity
内部直接分发呢?主要是为了兼顾不是继承自 AppCompatActivity
的场景。有可能是直接继承自 Activity
,然后自己实现了 Lifecycle
接口。
public class ReportFragment extends Fragment {
// 增加dispatch重载,尝试获取Activity中的LifecycleRegistry并调用 handleLifecycleEvent
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);
}
}
}
// 2.各个生命周期方法里面都调用了dispatch()方法
@Override
public void onStart() {
super.onStart();
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
dispatch(Lifecycle.Event.ON_RESUME);
}
@Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}
//······
// 3.拿到Activity的Lifecycle对象,把当前的事件分发给每个观察者
private void dispatch(@NonNull Lifecycle.Event event) {
if (Build.VERSION.SDK_INT < 29) {
// 在API 29之前从ReportFragment分派事件。
// 在API 29+上,由reportfragment.injectifneededdin中添加的activitylifecyecallbacks处理
dispatch(getActivity(), event);
}
}
}
为了前向兼容,ReportFragment
依然会被添加到 Activity,并在 dispatch()
中增加过滤避免出现二次调用。
ReportFragment
会在侦测到 Activity 生命周期变化的时候调用 LifecycleRegistry.handleLifecycleEvent()
传入对应的状态。
这时候会有一个类 LifecycleDispatcher
:
//挂钩到Activity的回调并进行观察
class LifecycleDispatcher {
private static AtomicBoolean sInitialized = new AtomicBoolean(false);
static void init(Context context) {
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
}
static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
// 监听到每个Activity打开的事件
ReportFragment.injectIfNeededIn(activity);
}
}
}
在它的 init()
方法里面调用了 registerActivityLifecycleCallbacks()
,这里就能监察到每个 Activity 打开的事件,会再次利用 ReportFragment.injectIfNeededIn(activity)
,也就是说往每个 Activity 里面注册一个 ReportFragment
,用于分发和报告当前宿主的生命周期到每个观察者,它这里是以一个切面编程的方式注入了一个 Fragment 对象,尽管我们是继承子 Activity,只要你实现了 LifecycleOwner
的接口,也能具备生命周期分发的能力。所以 Activity 生命周期分发的功能提取到 ReportFragment
里面,主要是为了不是继承自 AppCompatActivity
的场景。
到这里 Activity/Fragment 各自是如何实现 Lifecycle
能力的已经分析完成。但是无论如何生命周期能力都是依赖 LifecycleRegistry
来完成的。
它是 Lifecycle
的实现,可以处理多个观察者。生命周期事件分发都是依靠 LifecycleRegistry
来完成的。先从添加观察者方法开始:
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("addObserver");
// 1.初始化状态,当前宿主的状态
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// 2.将observer封装成 ObserverWithState,是一个拥有宿主状态的观察者
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 添加到Map集合中
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
// 3.计算出它应该到达的状态,也就是当前宿主的状态
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
// 4.在while()循环中,会让当前的观察者的状态从init状态前进到当前宿主的状态
//Observer的状态与targetState比较,如果小于0说明观察者的状态还没有到达targetState的状态
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
// 5.让Observer的状态前进到targetState
final Event event = Event.upFrom(statefulObserver.mState);
// 6. 分发事件
statefulObserver.dispatchEvent(lifecycleOwner, event);
popParentState();
// 从新计算mState
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
//同步状态
sync();
}
}
在 addObserver(observer)
里面,初始化状态,并且把observer封装成一个ObserverWithState
,一个拥有宿主状态的观察者,然后添加到Map集合当中。
这里主要做了四件事:
ObserverWithState
,是一个拥有初始状态的观察者;dispatchEvent()
分发事件。每个步骤都很重要,我们来一一分析:
State
是一个枚举,表示宿主的状态,但是宿主的状态和宿主的生命周期不是同一个概念。
public enum State {
// 宿主的销毁状态,onDestory()之后
DESTROYED,
// 宿主的初始状态,onCreate()之前
INITIALIZED,
// 宿主的创建状态,onCreate()之后,onStop()之前
CREATED,
// 宿主的启动状态,onStart()之后,onPasue()之前
STARTED,
// 恢复状态,onResume()之后
RESUMED;
}
比如宿主切换到后台,会执行 onPause()
方法,那么宿主的状态是什么状态?再从后台切回前台会执行 onStart()
再执行 onResum()
,所以切换到后台的时候,执行了 onPause
这个事件,它的状态会变成 STARTED 的状态。可以看到它是没有 PAUSE 状态的。
这里还定义了 Event
事件,一个枚举,表示生命周期事件。它与宿主的生命周期一一对应。
public enum Event {
//LifecycleOwner的onCreate事件的常量
ON_CREATE,
//LifecycleOwner的onStart事件的常量
ON_START,
//LifecycleOwner的onResume事件的常量
ON_RESUME,
//LifecycleOwner的onPause事件的常量
ON_PAUSE,
//LifecycleOwner的onStop事件的常量
ON_STOP,
//LifecycleOwner的onDestroy事件的常量
ON_DESTROY,
//可以匹配所有事件的常量
ON_ANY
}
宿主生命周期与宿主状态关系图:
宿主在创建之初肯定是处于 INITIALIZED 状态,执行了 onCreate()
方法之后就会进入 CREATED 状态,接着执行了 onStart()
方法之后就会进入 STARTED 状态,执行了 onResume()
就会进入 RESUMED 状态,这是生命周期前进的过程,生命周期倒退过程同理。这里就是宿主的生命周期状态和事件完整的流程。
回到 addObserver()
方法中:
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("addObserver");
// 1.获取observer需要设置的初始状态
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// 2.将observer封装成 ObserverWithState,并绑定初始的生命周期状态
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 添加到Map集合中
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
// 3.计算出它应该到达的目标状态
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
// 4.在while()循环中,会让当前的观察者的状态从init状态前进到目标状态
//Observer的状态与targetState比较,如果小于0说明观察者的状态还没有到达targetState的状态
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
// 5.让Observer的状态升级到targetState
final Event event = Event.upFrom(statefulObserver.mState);
// 6. 分发事件,同步状态
statefulObserver.dispatchEvent(lifecycleOwner, event);
popParentState();
// 重新计算mState
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
//同步状态
sync();
}
}
在初始状态中,只要不是在 onDestory
注册的 Observer
,每个观察者的初始状态都是 INITIALIZED 状态。在 while 循环中,会让当前的观察者的状态从 INITIALIZED 状态升级到目标状态,如果观察者的状态小于目标状态,就会通过 Event.upFrom()
方法让生命周期升级。
比如我们在 onResme()
方法中注册一个观察者,那么它会接收到哪几种状态呢?INITIALIZED、ONSTART、ONRESUME 它都会有,这个逻辑就在 while 循环里面,先通过 calculateTargetState(observer)
计算出它应该到达的目标状态,也就是当前宿主的状态,然后会拿 Observer 的状态比较,如果小于0说明观察者的状态还没有到达 targetState 的状态,那么就会让 Observer 的状态升级到 targetState。那么是如何进行升级的呢?
// 计算传入状态升级所对应的事件
public static Event upFrom(@NonNull State state) {
switch (state) {
case INITIALIZED:
return ON_CREATE;
case CREATED:
return ON_START;
case STARTED:
return ON_RESUME;
default:
return null;
}
}
离开当前的状态到达更高的状态,事件的状态从较低向上升级。在 INITIALIZED 状态中接收的是 on_Create 事件,然后来到 dispatchEvent()
方法里面:
static class ObserverWithState {
// 当前状态
State mState;
// Observer封装
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
//事件分发逻辑
void dispatchEvent(LifecycleOwner owner, Event event) {
//根据Event获取目标状态
State newState = event.getTargetState();
// 获取最小状态
mState = min(mState, newState);
// 状态改变回调
mLifecycleObserver.onStateChanged(owner, event);
// 更新当前状态
mState = newState;
}
}
会根据 Event
反推出目标状态,在 event.getTargetState()
里面,如果 Event
事件是 ON_CREATE 那么就会到达 State.CREATED
的状态,在调用 mLifecycleObserver.onStateChanged(owner, event)
之后,mState = newState
状态就变成新的状态,前进了一步,从 INITIALIZED 状态变成了 CREATED 状态。
// 获取事件目标状态
public State getTargetState() {
switch (this) {
// 如果事件是 ON_CREATE或者ON_STOP,那么状态会到达State.CREATED
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;
}
}
它在分发事件的时候是根据观察者的状态推导出分发的事件,然后再根据分发的事件推导出观察者的状态,在这个方法执行完后,会再次回到While()循环中,再次进行观察者状态与目标状态比较,当前状态 mState 已经变成 CREATE,
如果 targetState 是 INITIALIZED,那么就实现了状态的升级。
但是如果 targetState 是 RESUME,while循环比较还是小于0的,则会再次调用 Event.upFrom(mState)
和 dispatchEvent()
方法,将状态升级到 STATED,继续循环升级到 RESUME,依此类推,mState = newState
状态就变成新的状态 RESUME。直到观察者的状态和宿主的状态达到一致,然后退出While()循环,如下图
ObserverWithState
被创建之初状态为 INITIALIZED,如果在宿主的 onResume() 生命周期注册一个 Observer,会把宿主的 onCreate,onStart,onResume 都分发给 Observer:
直到 Observer 的状态和宿主的状态对齐为止,而不是直接从 INITIALIZED 状态直接分发一个 RESUME 直接到达 RESUME,目的因为我们可以在任何地方注册,并且可以接收到完整的接收事件,从而完成初始化,暂停,释放的工作。
这是添加观察者时的事件分发流程。
那么宿主的生命周期变化之后是如何分发给每一个观察者的?
根据上面 Activity/Fragment 源码分析,它会在每个生命周期方法里面执行handleLifecycleEvent(event)
,event.getTargetState()
根据当前的事件推导出每个观察者目标的生命周期状态。
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
enforceMainThreadIfNeeded("handleLifecycleEvent");
moveToState(event.getTargetState());
}
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
mHandlingEvent = true;
// 同步新状态事件
sync();
mHandlingEvent = false;
}
moveToState(next)
里面主要是做一些条件的判断,真正的状态同步是在 sync()
方法里面:
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
//循环,直到isSynced()同步完成,所有观察者的状态都分发完,状态都与宿主的状态一致
while (!isSynced()) {
mNewEventOccurred = false;
// 1.宿主的状态小于观察者状态,观察者状态进行降级
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
//状态降级
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
// 2. 宿主的状态大于观察者状态,观察者状态进行升级
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
// 状态升级
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
isSynced()
判断这个接口里面注册的 Observer 是否所有观察者的状态都分发完成,都已经同步到跟宿主一致的状态。如果不是则进入状态判断:
如果宿主的状态小于观察者状态,这种发生在生命周期倒退的阶段,比如前台切换到后台,执行 onPause()
方法,宿主进入 STARED 状态,观察者还处于 RESUME 状态,backwardPass()
是让所有的观察者都倒退,和宿主一样的状态,并且分发相应的事件给他们,
private void backwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
mObserverMap.descendingIterator();
// 循环遍历所有观察者
while (descendingIterator.hasNext() && !mNewEventOccurred) {
Map.Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
ObserverWithState observer = entry.getValue();
// 循环对比单个观察者的状态,直到单个观察者同步到目标状态,观察者状态大于宿主状态,则将观察者状态降级处理
while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
// 根据observer.mState 的状态降级,获取对应的Event事件
Event event = Event.downFrom(observer.mState);
pushParentState(event.getTargetState());
// 分发相应的事件Event
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
这里的核心逻辑就是遍历所有观察者,根据当前观察者的状态,计算出它应该分发哪一种事件,由于是生命周期的倒退,这里执行的是 Event.downFrom(observer.mState)
,也就是生命周期的降级:
// 计算传入状态降级所对应的事件
public static Event downFrom(@NonNull State state) {
switch (state) {
// 如果当前的状态是 CREATED,发生生命周期倒退就是执行了ON_DESTROY,返回ON_DESTROY事件
case CREATED:
return ON_DESTROY;
case STARTED:
return ON_STOP;
case RESUMED:
return ON_PAUSE;
default:
return null;
}
}
如果观察者是 RESUME 状态,发生生命周期倒退,就会返回一个 ON_PAUSE 事件,如果是 STARTED 状态发生生命周期的倒退也就是返回 ON_STOP 事件。
然后根据返回的事件,调用 observer.dispatchEvent()
分发给它,根据上面的分析,还会当前的事件推导出目标的状态,然后赋值给 mState。
static class ObserverWithState {
void dispatchEvent(LifecycleOwner owner, Event event) {
//根据Event获取目标状态
State newState = event.getTargetState();
// 获取最小状态
mState = min(mState, newState);
// 状态改变回调
mLifecycleObserver.onStateChanged(owner, event);
// 更新当前状态
mState = newState;
}
}
backwardPass()
执行完之后,观察者的状态就会降级到和宿主一样的状态,直到集合里面的所有观察者的状态和宿主的一样为止。
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
//所有观察者的状态都分发完,状态都与宿主的状态一致
while (!isSynced()) {
// ······
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
// 2. 宿主的状态和Observe状态比较,宿主的状态大于观察者状态,观察者状态进行升级
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
// 状态升级
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
同理,进入 sync()
的第二个判断条件,把当前宿主的状态和每个观察者的状态进行比较,如果大于0,生命周期前进(比如后台切换到前台),从 STARTES 状态切换到 RESUME 状态, forwardPass(lifecycleOwner)
逻辑与 backwardPass()
相似,只不过这是状态前进的过程,会调用 Event.upForm(observer.mState)
,根据当前观察者的状态在生命周期前进的时候计算出它应该分发哪一个事件。
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);
// 根据mState状态升级,获取对应的分发事件Event
final Event event = Event.upFrom(observer.mState);
// 分发完后就和宿主达到一致的状态
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
observer.dispatchEvent()
分发完就会与宿主达到一致的状态,直到 Observer 集合当中所有观察者与宿主的状态保持一致,并且退出这个循环。
到这里,宿主的生命周期和宿主状态的关系,每个生命周期变化的时候,都会分发相应的事件,并且根据这个事件推导出宿主的状态,遍历所有的观察者,让他们的状态也随之升级,或者降级,并且把本次事件分发给观察者。
那么这个事件它在分发的时候,是如何区分的 LifecycleObserver
还是 FullLifecycleObserver
,亦或者是 LifecycleEventObserver
这三种类类型的?在 addObserver()
里面,每次注册一个 Observer 都会把它包装成一个 ObserverWithState
:
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
//把传递进来的observer转换成LifecycleEventObserver
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;
}
}
它把传递进来的 observer 转换成 LifecycleEventObserver
,分发事件的时候调用了 mLifecycleObserver.onStateChanged()
方法,但是我们在使用的时候明明是 LifecycleObserver
或者 FullLifecycleObserver
,主要是原理在 Lifecycling.lifecycleEventObserver(observer)
里面,本质上是一个工具类,把传递进来的 observer 转化成 LifecycleEventObserver
,主要是通过适配器来转化的。
static LifecycleEventObserver lifecycleEventObserver(Object object) {
// 是否为LifecycleEventObserver类型
boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
// 是否为FullLifecycleObserver类型
boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
// 1.这种情况发生在自定义Observer,上面两种都实现了
if (isLifecycleEventObserver && isFullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
(LifecycleEventObserver) object);
}
// 2. FullLifecycleObserver 将object当做FullLifecycleObserver传递
if (isFullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
}
// 3. LifecycleEventObserver 直接返回object本身
if (isLifecycleEventObserver) {
return (LifecycleEventObserver) object;
}
//······
}
LifecycleEventObserver && FullLifecycleObserver
,如果条件都成立(一般发生在自定义的 Observer,即实现了两个接口),返回了一个FullLifecycleObserverAdapter
,它实现了 LifecycleEventObserver
接口,复写了onStateChanged()
方法,判断 Event
的类型,从而回调传递进来的 FullLifecycleObserver
相应的方法,如果还实现了 mLifecycleEventObserver
接口,则最后还会回调mLifecycleEventObserver.onStateChanged()
方法。// 实现LifecycleEventObserver接口
class FullLifecycleObserverAdapter implements LifecycleEventObserver {
// mFullLifecycleObserver回调生命周期方法
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
switch (event) {
case ON_CREATE:
mFullLifecycleObserver.onCreate(source);
break;
case ON_START:
mFullLifecycleObserver.onStart(source);
break;
case ON_RESUME:
mFullLifecycleObserver.onResume(source);
break;
case ON_PAUSE:
mFullLifecycleObserver.onPause(source);
break;
case ON_STOP:
mFullLifecycleObserver.onStop(source);
break;
case ON_DESTROY:
mFullLifecycleObserver.onDestroy(source);
break;
}
// 回调mLifecycleEventObserver的onStateChanged()方法
if (mLifecycleEventObserver != null) {
mLifecycleEventObserver.onStateChanged(source, event);
}
}
}
如果仅仅是实现了 FullLifecycleObserver
,同样是返回了一个FullLifecycleObserverAdapter
,但是 lifecycleEventObserver
为 null,说明不再回调 onStateChanged(source, event)
方法,实际上通过 FullLifecycleObserverAdapter
包装实现转化过程,将 LifecycleObserver
转化为 LifecycleEventObserver
。
如果是直接实现了 LifecycleEventObserver
的则直接返回,那么在生命周期事件分发的时候, Observer 就能直接分发到 onStateChanged()
这个方法里面。
static LifecycleEventObserver lifecycleEventObserver(Object object) {
·····
final Class<?> klass = object.getClass();
// 获取Observer构造器类型,是否添加了注解编译器
int type = getObserverConstructorType(klass);
// 提供了两种策略
if (type == GENERATED_CALLBACK) {
//提供了两种策略
List<Constructor<? extends GeneratedAdapter>> constructors =
sClassToAdapters.get(klass);
if (constructors.size() == 1) {
GeneratedAdapter generatedAdapter = createGeneratedAdapter(
constructors.get(0), object);
return new SingleGeneratedAdapterObserver(generatedAdapter);
}
GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
for (int i = 0; i < constructors.size(); i++) {
adapters[i] = createGeneratedAdapter(constructors.get(i), object);
}
// 返回CompositeGeneratedAdaptersObserver
return new CompositeGeneratedAdaptersObserver(adapters);
}
// 返回ReflectiveGenericLifecycleObserver,内部实现依赖反射
return new ReflectiveGenericLifecycleObserver(object);
}
上面的代码则是判断 LifecycleOberver
,我们知道它只是一个空实现,但是为什么还要定义这个接口呢?这里仅仅是起到一个约束和规范的作用,方便在运行的时候判断 Observer 是那种类型。
public interface LifecycleObserver {
}
如果 Observer 是实现了 LifecycleOberver
这个接口的,它在运行的时候,分发事件的时候它提供了两种策略:
ReflectiveGenericLifecycleObserver
,同样是实现了LifecycleEventObserver
,在 onStateChanged()
调用了 invokeCallbacks()
方法通过反射的形式来调用自定义的 Observer 中相关方法。// LifecycleObserver内部实现依赖反射
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) {
//通过反射的形式来调用自定义的Observer中相关方法
mInfo.invokeCallbacks(source, event, mWrapped);
}
}
比如上面 Lifecycle 实现方式的第一种:
public class MyLifecycleObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onStart(@NotNull LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onStop(@NotNull LifecycleOwner owner) {
}
}
编译时会在 build.generated.source.kapt.debug
文件下自动生成MyLifecycleObserver_LifecycleAdapter.java
文件,在它的实现里面,就是根据事件的类型,回调到 MyLifecycleObserver
的 onStart()
和 onStop()
方法,这里为什么能直接回调呢?因为它在编译阶段生成的这个类,就能扫描到 MyLifecycleObserver
中的方法上标记的注解OnLifecycleEvent
,然后拿到方法的名称,以及它的参数,生成下面的源码,就不用使用反射调用 MyLifecycleObserver
类中的方法了。
但是如何判断有没有引入 lifecycle-compiler
这个编译器的,通过 int type = getObserverConstructorType(klass)
判断构造器类型,跟踪来到 generatedConstructor()
中:
// 传入一个Class,实际上是就是上面定义的MyLifecycleObserver
private static Constructor<? extends GeneratedAdapter> generatedConstructor(Class<?> klass) {
try {
//获取包名
Package aPackage = klass.getPackage();
//获取类名
String name = klass.getCanonicalName();
final String fullPackage = aPackage != null ? aPackage.getName() : "";
// 获取adapterName拼接后的类名
final String adapterName = getAdapterName(fullPackage.isEmpty() ? name :
name.substring(fullPackage.length() + 1));
final Class<? extends GeneratedAdapter> aClass =
(Class<? extends GeneratedAdapter>) Class.forName(
fullPackage.isEmpty() ? adapterName : fullPackage + "." + adapterName);
Constructor<? extends GeneratedAdapter> constructor =
aClass.getDeclaredConstructor(klass);//反射加载这个类,
if (!constructor.isAccessible()) {//如果没有异常,说明类存在
constructor.setAccessible(true);
}
return constructor;
} catch (ClassNotFoundException e) {
return null;
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
adapterName 的类名拼接,实际上是 MyLifecycleObserver
拼接上 _LifecycleAdapter
,如下:
public static String getAdapterName(String className) {
return className.replace(".", "_") + "_LifecycleAdapter";
}
如果类存在了,说明引入了 lifecycle-compiler
这个编译器,如果抛出异常就说明没有引入这个编译器。
这样它就能够区分,对于是直接实现 LifecycleObserver
的情况,是返回 CompositeGeneratedAdaptersObserver
还是返回 ReflectiveGenericLifecycleObserver
,从而采用不同的策略来回调方法。
Lifecycle
原理时序图如下:
observer.dispatchEvent()
分发事件。关于 Lifecycle
面试常问几个问题:
答:是通过添加透明 ReportFragment.
答:能。
Lifecycle
几乎是 Jetpack 组件的核心,所有具有生命周期感知能力的组件都会用到 Lifecycle
,包括 ViewModel和 Livedata。Lifecycle
实现了执行的逻辑和活动的分离,代码解耦并且增加了代码的额可读性。Lifecycle
在活动结束时自动移除监听,避免了生命周期的问题。
总的来说,观察宿主生命周期有三种写法,推荐第二种和第三种,第一种需要使用注解标记,要么是反射,要么是要添加注解处理器,生成适配的类。
这是一个Jetpack组件 + MVVM架构模式
的开源实战项目,加入 组件化
、模块化
、协程
、Flow
、短视频
,打造一个大型的 Android 项目架构。项目地址:https://github.com/suming77/SumTea_Android
好了各位,以上就是这篇文章的全部内容了,很感谢您阅读这篇文章。我是suming,感谢各位的支持和认可,您的点赞就是我创作的最大动力。山水有相逢,我们下篇文章见!
本人水平有限,文章难免会有错误,请批评指正,不胜感激 !