天天看點

淺析 - Android Lifecycle Component前言簡要介紹相關類Lifecycle的初始化流程怎樣的?Lifecycle的狀态如何改變以及如何分發的?Lifecycle是如何解析生命周期狀态的?

淺析 - Android Lifecycle Component

  • 前言
  • 簡要介紹相關類
  • Lifecycle的初始化流程怎樣的?
  • Lifecycle的狀态如何改變以及如何分發的?
  • Lifecycle是如何解析生命周期狀态的?

前言

關于

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

标記一個類可以接收生命周期事件的回調。

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

的初始化流程。

淺析 - Android Lifecycle Component前言簡要介紹相關類Lifecycle的初始化流程怎樣的?Lifecycle的狀态如何改變以及如何分發的?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()

内部做了兩件事:

  1. 擷取事件對應的下一個狀态
  2. 改變目前狀态到下一個狀态,并同步分發事件

雖然

getStateAfter()

很短,但是還是看圖更易了解:

假設

ReportFragment

分發了

Lifecycle.Event.ON_RESUME

,那麼根據這個方法,可以得到對應的狀态為

RESUMED

淺析 - Android Lifecycle Component前言簡要介紹相關類Lifecycle的初始化流程怎樣的?Lifecycle的狀态如何改變以及如何分發的?Lifecycle是如何解析生命周期狀态的?

最後關鍵的步驟就是将各個觀察者的生命周期狀态依次移動到正确的狀态,

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));
            ...
        }
    }
}
           

最後已一個時序圖結尾:

淺析 - Android Lifecycle Component前言簡要介紹相關類Lifecycle的初始化流程怎樣的?Lifecycle的狀态如何改變以及如何分發的?Lifecycle是如何解析生命周期狀态的?

Lifecycle是如何解析生命周期狀态的?

因為觀察者内部是使用注解來标記生命周期方法的,也就不可避免的需要使用的反射。為了反射開銷比較大,是以使用了

ClassInfoCache

作為緩存。 整個流程比較簡單,就不詳細介紹了。

class MyObserver : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun create() {
        Log.d(TAG, "create() called ")
    }
}
           
淺析 - Android Lifecycle Component前言簡要介紹相關類Lifecycle的初始化流程怎樣的?Lifecycle的狀态如何改變以及如何分發的?Lifecycle是如何解析生命周期狀态的?