Q:什么是LifeCycle
androidx.lifecycle
软件包提供了可用于构建生命周期感知型组件的类和接口,可执行操作来响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。
Q: 请说说LifeCycle的好处?
(1)我们在Activity的onCreate()中初始化某些成员(比如MVP架构中的Presenter,或者AudioManager、MediaPlayer等),然后在onStop中对这些成员进行对应处理,在onDestroy中释放这些资源,最终会有太多的类似调用并且会导致 onCreate() 和 onDestroy() 方法变的非常臃肿。比如定位组件,在onCreate中定义,在onStart中启动,在onStop中停止,在onDestory中销毁;同样的,录音组件也将有这一系列的生命周期,如果一个Activity中包含了若干个这样的组件,则会在生命周期方法中放置大量的代码,这使得它们难以维护。
(2)无法保证组件会在 Activity 或 Fragment 停止之前启动。在我们需要执行长时间运行的操作(如
[onStart()]
中的某种配置检查)时尤其如此。这可能会导致出现一种竞态条件,在这种条件下,[onStop()]
方法会在[onStart()]
之前结束,这使得组件留存的时间比所需的时间要长。
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, location -> {
// update UI
});
}
@Override
public void onStart() {
super.onStart();
Util.checkUserStatus(result -> {
// 有可能onStop()执行完毕了,回调还没有得到执行
if (result) {
myLocationListener.start();
}
});
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
}
}
[
androidx.lifecycle
] 软件包提供的类和接口可帮助您以弹性和隔离的方式解决这些问题,它将生命周期的响应分发到各个观察者中去
Q: 说说LifeCycle相关组件所扮演的角色?
-
LifecycleOwner
: 提供了获取Lifecycle接口实现的方法。通过LifecycleOwner,将Lifecycle的实现和Activity等生命周期组件解耦。可以把LifecycleOwner理解为Lifecycle的“工厂”。
Lifecycle
:是被观察者,用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态LifecycleObserver
:观察者,可以通过被LifecycleRegistry类通过 addObserver(LifecycleObserver o)方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner对应的生命周期事件
以上三者的持有关系:
LifecycleOwner -> Lifecycle -> (n) LifecycleObserver
Lifecycle.Event
:分派的生命周期事件。这些事件映射到 Activity 和 Fragment 中的回调事件。
Lifecycle.State
:Lifecycle组件的当前状态。
LifecycleRegistry
: 添加观察者,响应生命周期事件,负责转发生命周期
Q: State和组件(Activity/Fragment)生命周期的对应关系?
- INITIALIZED:对应Activity已实例化但在onCreate之前的生命周期
- DESTROYED:此后,LifyCycle不再分派生命周期事件。此状态在Activity.onDestroy()之前
- CREATED:对应Activity的onCreate之后和onStop之前的生命周期
- STARTED:对应Activity的onStart之后和onPause之前的生命周期
- RESUMED:对应Activity的onResume
Q:Lifecycle是怎样感知生命周期的?
AppComponent实现了LifycycleOwer接口声明了mLifecycleRegistry对象,但是没有直接使用其进行生命周期的分发,而是被ReportFragment通过activity.getLifecycle()获取使用。
ActivityAppCompatActivity中添加了一个ReportFragment,其生命周期变化时,调用LifecycleRegistry.handleLifecycleEvent()方法通知LifecycleRegistry改变状态,LifecycleRegistry内部调用moveToState()改变状态,并调用每个LifecycleObserver.onStateChange()方法通知生命周期变化。
image.png
Q:ReportFragment是如何被添加到Activity中的呢?
ReportFragment可以通过两种方式添加到Activity中。
1.如果Activity继承自ComponentActivity(AppCompatActivity的间接父类),ComponentActivity的onCreate方法中会调用ReportFragment的injectIfNeededIn(Activity)静态方法完成注入。
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
2.如果Activity没有继承自ComponentActivity,Lifecycle使用LifecycleDispatcher类完成ReportFragment的注入。
LifecycleDispatcher和ProcessLifecycleOwner使用相同的方式跟随进程初始化(后文会提到),LifecycleDispatcher在其静态方法init(Context)中,使用Application.registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks)方法向Application中注册了Activity生命周期回调监听器。在监听器的onActivityCreated(Activity, Bundle)回调方法(Activity创建时回调)中,调用ReportFragment.injectIfNeededIn(Activity)方法将ReportFragment注入到Activity中。
Q:为什么不直接在SupportActivity的生命周期函数中给Lifecycle分发生命周期事件,而是要加一个Fragment呢?
因为不是所有的页面都继承AppCompatActivity,为了兼容非AppCompatActivity,所以封装一个同样具有生命周期的Fragment来给Lifecycle分发生命周期事件。
Q:那我们不继承新版本AppCompatActivity时,Lifecycle是如何通过ReportFragment来分发生命周期事件的呢?
除了ComponentActivity以外,还有两个地方使用到了ReportFragment:LifecycleDispatcher和ProcessLifecycleOwner
- LifecycleDispatcher
LifecycleDispatcher是通过注册Application.registerActivityLifecycleCallbacks来监听Activity的生命周期回调的。
- 在onActivityCreated()中添加ReportFragment,将Activity的生命周期交给ReportFragment去分发给LifecycleRegistry
- 在onActivityStopped()以及onActivitySaveInstanceState()中,将Activity及其所有子Fragment的State置为CREATED
- ProcessLifecycleOwner
- ProcessLifecycleOwner是用来监听Application生命周期的,因此它只会分发一次ON_CREATE事件,并且不会分发ON_DESTROY事件
- ProcessLifecycleOwner在Activity的onPause和onStop方法中都采用了Handle.postDelayed()方法,是为了处理Activity重建时比如横竖屏幕切换时,不会发送事件。
- ProcessLifecycleOwner一般用来判断应用是在前台还是后台。但由于使用了Handle.postDelayed(),因此这个判断不是即时的,有默认700ms的延迟。
- ProcessLifecycleOwner与LifecycleDispatcher一样,都是通过注册Application.registerActivityLifecycleCallbacks来监听Activity的生命周期回调,来给每个Activity添加ReportFragment的。
Q: ProcessLifecycleOwner和LifecycleDispatcher两个类是在哪里初始化呢?
从源码中我们看到,Lifecycle自动在我们的AndroidManifest.xml中添加了一个ContentProvider,用于初始化ProcessLifecycleOwner和LifecycleDispatcher,这么做的好处是,不需要我们在Application中显示调用,不需要我们写一行代码。
Q:为什么LifecycleRegistry不是直接分发Event而是先计算State,再反推Event进行分发呢?
LifecycleRegistry的实现充分考虑了各种情况下事件分发的准确性,主要有两类问题:1. 可重入,2. 一致性。
这里的两次转换主要为了解决第2个问题,为了保证不同生命周期添加的观察者都能正确收到状态变换时的各种事件(一致性),不会漏掉,LifecycleRegistry通过两次转换实现了重放。
Q: FastSafeIterableMap的特性?
- Map,K-V结构存储。
- 有序,插入顺序决定保存顺序。支持正向、反向遍历。
- 支持在遍历过程中添加、移除元素。(影响LifecycleRegistry的可重入性)
LifecycleRegistry利用FastSafeIterableMap有序的特性,保证添加的Observer按照插入顺序,State从大到小的顺序排列。所以判断同步完成,只需要看第一个Observer和最后一个Observer的状态相等,并且等于LifecycleRegistry的状态。
Q: 如何保证FastSafeIterableMap中存放的ObserverWithState对象的state状态总是先入的会比后入的大?
sync方法因为在提升状态时从前向后遍历,降低状态时从后向前遍历,所以一定能保证执行过程中的状态要求;在有新Observer添加的情况下,也可通过防止重入的方式保证在任何时刻mObserverMap中前面的Observer的状态,一定要大于等于后面的Observer的状态。
Q:LifeCycle怎么防止LifeCycleObserver的重入操作?
LifecycleRegistry在处理生命周期事件时,只要涉及到分发事件,都可能出现重入的场景。因为在事件处理方法中,可能添加新的Observer或者移除现有的Observer,对Observer集合的修改,就是修改了外部变量。
LifecycleRegistry通过parentState缓存嵌套调用情况下上层调用时的状态,来保证下层调用方法执行时,要同步到的目标状态,不会超过上层状态,甚至是当上层的Observer已经被移除的情况(如果没有parentState缓存,后添加的Observer的状态就可能比先添加的Observer的状态更早同步到目标状态)。
这里的状态反映到调用者,更多体现在回调方法的调用顺序上。以onStart方法为例,先添加的Observer(A)的onStart方法,一定比后添加的Observer(B)的onStart方法先执行完成。即便是B在A的onStart方法中添加的情况下(A.onStart执行完成后,B.onStart方法才会执行)。
Q:LifeCycle使用了哪些设计模式
观察者模式:AppCompatActivity中添加了一个ReportFragment,其生命周期变化时,调用LifecycleRegistry.handleLifecycleEvent()方法通知LifecycleRegistry改变状态,LifecycleRegistry内部调用moveToState()改变状态,并调用每个LifecycleObserver.onStateChange()方法通知生命周期变化。
适配器模式:在ObserverWithState
静态内部类中, 使用适配器模式对传入的Observer进行封装,通过Lifecycling转为统一的LifecycleEventObserver
对象,并同时保存对应的mState状态。
Q:LifecycleRegistry 会将外部传入的所有 LifecycleObserver 根据 Lifecycling 包装成 LifecycleEventObserver 对象,这里先来解释下为什么需要进行这层包装?
1.LifecycleEventObserver 和 FullLifecycleObserver 都是继承于 LifecycleObserver 的接口,如果开发者自己实现的自定义 Observer 同时实现了这两个接口,那按道理来说 LifecycleRegistry 就必须在有事件触发的情况下同时回调这两个接口的所有方法
2.如果开发者自己实现的自定义 Observer 仅实现了 LifecycleEventObserver 和 FullLifecycleObserver 这两个接口当中的一个,那么也需要在有事件触发的情况下调用相应接口的对应方法
3.除了通过以上两个接口来实现回调外,Google 也提供了通过注解的方法来声明生命周期回调函数,此时就只能通过反射来进行回调
基于以上三点现状,如果在 LifecycleRegistry 中直接对外部传入的 Observer 来进行类型判断、接口回调、反射调用等一系列操作的话,那势必会使得 LifecycleRegistry 整个类非常的臃肿,所以 Lifecycling 的作用就是来将这一系列的逻辑给封装起来,仅仅开放一个 onStateChanged 方法即可让 LifecycleRegistry 完成整个事件分发,从而使得整个流程会更加清晰明了且职责分明。