浅析 - Android Lifecycle Component
前言
关于Lifecycle
基础相关的使用与概念请移步这里:
- https://blog.csdn.net/guiying712/article/details/81176039#处理-onstop-事件
- https://developer.android.com/topic/libraries/architecture/lifecycle?hl=zh-cn
提出几个问题,方便下面一一回答:
Lifecycle
的初始化流程怎样的?Lifecycle
的状态如何改变以及如何分发的?Lifecycle
是如何解析生命周期状态的?
简要介绍相关类
Lifecycle
其内部定义了具有Android生命周期的事件与状态。
LifecycleOwner
代表具有Android生命周期的类。 它最主要的实现类就是AppCompatActivity
。
LifecycleObserver
标记一个类可以接收生命周期事件的回调。
LifecycleRegister
是Lifecycle
的具体实现,可以处理多个观察者,内部用来处理状态,分发事件。
!
Lifecycle的初始化流程怎样的?
一个组件再好用,如果不经过初始化,也是无根之水。 通过对生命周期注册流程的反跟踪,最后可以找到android.arch.lifecycle.ProcessLifecycleOwnerInitializer
类,它作为Lifecycle
组件初始化的开始。
由于其继承自ContentProvider
,那么必须要在AndroidManifest.xml
文件中显示注册ProcessLifecycleOwnerInitializer
才会被初始化。
在构建Apk的过程中,Android Studio会将多个模块的AndroidManifest.xml
合并到一起,所以查看一下build目录中,是否存在被合并的AndroidManifest.xml
文件。
app/build/intermediates/merged_manifests/debug/AndroidManifest.xml
可以很明显的看到<provider>
标签在AndroidManifest.xml
中被注册。
<application
.... >
....
<provider
android:name="android.arch.lifecycle.ProcessLifecycleOwnerInitializer"
android:authorities="com.example.application.lifecycle-trojan"
android:exported="false"
android:multiprocess="true" />
....
</application>
下面跟着一张时序图,来捋清楚Lifecycle
的初始化流程。
虽然涉及到的类很多,但是逻辑很多简单,都是直接初始化。
其中核心的逻辑就是监听Activity
和Fragment
的全局生命周期回调,最后在Activity
创建时向其中添加一个ReportFragment
,使用其作为生命周期的分发起始点。而当Activity
和Fragment
生命周期状态发生改变时,都通过LifecycleRegistryOwner
来处理生命周期状态的改变。
// 注册Activity的生命周期回调
((Application) context.getApplicationContext()).registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
// 注册Fragment的生命周期回调
((FragmentActivity) activity).getSupportFragmentManager() .registerFragmentLifecycleCallbacks(mFragmentCallback, true);
// injectIfNeededIn,添加ReportFragment到宿主Activity中。
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
Lifecycle的状态如何改变以及如何分发的?
@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);
}
上文曾说过,ReportFragment
是分发的核心类,当其生命周期变化时会分发对应的事件,最后走到LifecycleRegister.handleLifecycleEvent(Lifecycle.Event)
中。
handleLifecycleEvent()
内部做了两件事:
- 获取事件对应的下一个状态
- 改变当前状态到下一个状态,并同步分发事件
虽然getStateAfter()
很短,但是还是看图更易理解:
假设ReportFragment
分发了Lifecycle.Event.ON_RESUME
,那么根据这个方法,可以得到对应的状态为RESUMED
。
最后关键的步骤就是将各个观察者的生命周期状态依次移动到正确的状态,sync()
将该过程分为两个步骤,具体如下:
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
...
while (!isSynced()) {
mNewEventOccurred = false;
// 若最老的观察者状态大于当前状态,那么需要将最老的观察者状态向后移动
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
// 若最新的观察者状态小于当前状态,那么需要将最新的观察者状态向前移动
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (... mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
这里以将状态向前移动为例(CREATED => RESUME
)来分析下fowardPass()
方法:
private void forwardPass(LifecycleOwner lifecycleOwner) {
// 升序排序
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
...
// 若目标观察者的状态小于当前状态,那么当前状态对应的事件,并进行分发。
while ((observer.mState.compareTo(mState) < 0 && ... ) {
...
observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
...
}
}
}
最后已一个时序图结尾:
Lifecycle是如何解析生命周期状态的?
因为观察者内部是使用注解来标记生命周期方法的,也就不可避免的需要使用的反射。为了反射开销比较大,所以使用了ClassInfoCache
作为缓存。 整个流程比较简单,就不详细介绍了。
class MyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun create() {
Log.d(TAG, "create() called ")
}
}