浅析 - Android Lifecycle Component

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/biezhihua/article/details/82817946

前言

关于Lifecycle基础相关的使用与概念请移步这里:

  1. https://blog.csdn.net/guiying712/article/details/81176039#处理-onstop-事件
  2. https://developer.android.com/topic/libraries/architecture/lifecycle?hl=zh-cn

提出几个问题,方便下面一一回答:

  1. Lifecycle的初始化流程怎样的?
  2. Lifecycle的状态如何改变以及如何分发的?
  3. Lifecycle是如何解析生命周期状态的?

简要介绍相关类

Lifecycle 其内部定义了具有Android生命周期的事件与状态。

LifecycleOwner 代表具有Android生命周期的类。 它最主要的实现类就是AppCompatActivity

LifecycleObserver 标记一个类可以接收生命周期事件的回调。

LifecycleRegisterLifecycle的具体实现,可以处理多个观察者,内部用来处理状态,分发事件。

!

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的初始化流程。

在这里插入图片描述

虽然涉及到的类很多,但是逻辑很多简单,都是直接初始化。

其中核心的逻辑就是监听ActivityFragment的全局生命周期回调,最后在Activity创建时向其中添加一个ReportFragment,使用其作为生命周期的分发起始点。而当ActivityFragment生命周期状态发生改变时,都通过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()内部做了两件事:

  1. 获取事件对应的下一个状态
  2. 改变当前状态到下一个状态,并同步分发事件

虽然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 ")
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/biezhihua/article/details/82817946