天天看點

用fragment怎麼引入setcontentview_3. Jetpack源碼解析用Lifecycles管理生命周期1. 背景2. 基礎3. 源碼分析4. 總結5. 參考連結:

code小生,一個專注 Android 領域的技術平台 公衆号回複 Android 加入我的安卓技術群

作者:Hankkin

連結:https://juejin.im/post/5d15bbb86fb9a07f03574e56

聲明:本文已獲

Hankkin

授權發表,轉發等請聯系原作者授權

1. 背景

上一篇我門對Jetpack元件中的

Navigation

做了介紹,并且對其做了源碼分析,相信看過之後已經對此有了一定的了解,本篇文章我們會對

Lifecycles

進行使用及源碼的介紹,還沒看上篇的可以看一下:

系列文章:

1. Android_Jetpack元件---Naviagtion源碼解析

2. Jetpack源碼解析—Navigation為什麼切換Fragment會重繪?

2. 基礎

2.1 簡介

Lifecycles

是一個持有元件生命周期狀态(如Activity、Fragment)資訊的類,并允許其他對象觀察此狀态。可以幫助我們友善的管理

Activity

Fragment

的生命周期。

Lifecycle元件

中通過兩個枚舉類來跟蹤其關聯元件的生命周期:

用fragment怎麼引入setcontentview_3. Jetpack源碼解析用Lifecycles管理生命周期1. 背景2. 基礎3. 源碼分析4. 總結5. 參考連結:

2.2 基本使用

在我們的日常開發中,經常需要我們在Activity或者Fragment的生命周期方法中手動去管理一下資源的釋放等行為。舉個簡單的例子,當我們做自定義相機掃描的時候,camera相關的資源就需要我們手動的去釋放及開啟預覽;或者我們在使用MVP模式去開發的時候,P的建立和銷毀也需要我們在生命周期方法中去操作。

通過

Lifecycles元件

我們可以這樣使用:

我們可以定義一個Observer實作

LifecycleObserver

,并且在

Activity

或者

Fragment

中進行觀察:

下面是Activity:

啟動Activity,我們可以看到控制台中的列印日志:

通過控制台列印我們可以看到我們的觀察者Activity和被觀察者的日志均被列印了。具體是怎麼實作的呢?

3. 源碼分析

通過代碼我們大概能看出來

Lifecycles

元件是通過觀察者模式來實作的,接下來我們具體分析實作原理,我們發現在

Activity

Fragment

中可以直接通過

getLifecycle()

方法擷取到

Lifecycle

,那麼我們就從這裡入手:

3.1 getLifecycle()

我們點選進去發現ComponentActivity中實作了

LifecycleOwner

接口,

LifecycleOwner

接口中則聲明了

getLifecycle()

方法,而ComponentActivity中直接傳回了mLifecycleRegistry:

LifecycleRegistry

是個什麼東西呢?原來它繼承了Lifecycle

3.2 Lifecycle和LifecycleRegistry

我們看一下Lifecycle類:

Lifecycle中就是聲明了一些抽象方法和兩個狀态的枚舉類,具體的實作看LifecycleRegistry:

public class LifecycleRegistry extends Lifecycle {

// LifecycleObserver Map,每一個Observer都有一個State
    private FastSafeIterableMap mObserverMap = new FastSafeIterableMap<>();// 目前的狀态private State mState;// 生命周期擁有者,ComponentActivity繼承了LifecycleOwnerprivate final WeakReference mLifecycleOwner;//修改State值private void moveToState(State next) {if (mState == next) {return;
        }
        mState = next;if (mHandlingEvent || mAddingObserverCounter != 0) {
            mNewEventOccurred = true;// we will figure out what to do on upper level.return;
        }
        mHandlingEvent = true;
        sync();
        mHandlingEvent = false;
    }/**
    * 添加LifecycleObserver觀察者,并将之前的狀态分發給這個Observer,例如我們在onResume之後注冊這個Observer,
    * 該Observer依然能收到ON_CREATE事件
    */@Overridepublic void addObserver(@NonNull LifecycleObserver observer) {
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;//建立帶有狀态的觀察者
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
        ......// 例如:Observer初始狀态是INITIALIZED,目前狀态是RESUMED,需要将INITIALIZED到RESUMED之間的// 所有事件分發給Observerwhile ((statefulObserver.mState.compareTo(targetState) 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
            popParentState();
            targetState = calculateTargetState(observer);
        }
        ......
}/**
     * 同步Observer狀态,并分發事件
     */private void sync() {
        LifecycleOwner lfecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {
            Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "
                    + "new events from it.");return;
        }while (!isSynced()) {
            mNewEventOccurred = false;// State中,狀态值是從DESTROYED-INITIALIZED-CREATED-STARTED-RESUMED增大// 如果目前狀态值 if (mState.compareTo(mObserverMap.eldest().getValue().mState) 0) {
                backwardPass(lifecycleOwner);
            }
            Entry newest = mObserverMap.newest();// 如果目前狀态值 > Observer狀态值,需要通知Observer增大狀态值,直到等于目前狀态值if (!mNewEventOccurred && newest != null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);
            }
        }
        mNewEventOccurred = false;
    }/**
     * 向前傳遞事件,對應圖中的INITIALIZED -> RESUMED
     * 增加Observer的狀态值,直到狀态值等于目前狀态值
     */private void forwardPass(LifecycleOwner lifecycleOwner) {
        Iterator> ascendingIterator =
                mObserverMap.iteratorWithAdditions();while (ascendingIterator.hasNext() && !mNewEventOccurred) {
            Entry entry = ascendingIterator.next();
            ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                pushParentState(observer.mState);// 分發狀态改變事件
                observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
                popParentState();
            }
        }
    }/**
     * 向後傳遞事件,對應圖中的RESUMED -> DESTROYED
     * 減小Observer的狀态值,直到狀态值等于目前狀态值
     */private void backwardPass(LifecycleOwner lifecycleOwner) {
        Iterator> descendingIterator =
                mObserverMap.descendingIterator();while (descendingIterator.hasNext() && !mNewEventOccurred) {
            Entry entry = descendingIterator.next();
            ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                Event event = downEvent(observer.mState);// 分發狀态改變事件
                pushParentState(getStateAfter(event));
                observer.dispatchEvent(lifecycleOwner, event);
                popParentState();
            }
        }
    }
           

LifecycleRegistry

代碼我門看完了,注釋也已經很清楚了,基本作用就是添加觀察者,響應生命周期事件,分發生命周期事件的作用。

3.3 ReportFragment

接下來我們繼續分析

ComponentActivity

,我們在

onCreate()

聲明周期中發現一個比較熟悉

ReportFragment

,這個fragment我以前在做記憶體洩漏優化的時候經常碰到,在leakcanary中經常會報出這個類,是以這裡面看看

ReportFragment.injectIfNeededIn(this);

到底做了什麼?

檢視源碼我們發現,

ReportFragment

在每個生命周期中都做了分發事件的處理,通過調用

getLifecycle().handleLifecycleEvent(event)

來做生命周期的分發。意思也就是在

ComponentActivity

中添加了一個沒有頁面的

ReportFragment

,當Activity生命周期變化的時候,通過調用

LifecycleRegistry.handleLifecycleEvent()

方法通知LifecycleRegistry改變狀态,LifecycleRegistry内部調用

moveToState()

改變狀态,并調用每個LifecycleObserver.onStateChange()方法通知生命周期變化。

我們通過檢視ReportFragment調用,發現還有兩個類也調用了它,一個是

LifecycleDispatcher

,一個是

ProcessLifecycleOwner

,這兩個究竟是做什麼的呢?
用fragment怎麼引入setcontentview_3. Jetpack源碼解析用Lifecycles管理生命周期1. 背景2. 基礎3. 源碼分析4. 總結5. 參考連結:

3.4 LifecycleDispatcher

我們檢視源碼,發現在

init()

方法中,通過

Application

注冊了

DispatcherActivityCallback

,并且在

onActivityCreated

中将

ReportFragment

注入到Activity中。

3.5 ProcessLifecycleOwner

根據官方注釋,我們可以了解到:

  • ProcessLifecycleOwner是用來監聽Application生命周期的,是以它隻會分發一次ON_CREATE事件,并且不會分發ON_DESTROY事件。
  • ProcessLifecycleOwner在Activity的onResume和onStop方法中都采用了Handle.postDelayed()方法,是為了處理Activity重建時比如橫豎螢幕切換時,不會發送事件。
  • ProcessLifecycleOwner一般用來判斷應用是在前台還是背景。但由于使用了Handle.postDelayed(),是以這個判斷不是即時的,有預設700ms的延遲。
  • ProcessLifecycleOwner與LifecycleDispatcher一樣,都是通過注冊Application.registerActivityLifecycleCallbacks來監聽Activity的生命周期回調,來給每個Activity添加ReportFragment的。

看了着兩個類我們發現它們的入口均為

init()

,是以看一下誰調用了?

3.6 ProcessLifecycleOwnerInitializer

果真,在

ProcessLifecycleOwnerInitializer

onCreate()

中對這兩個進行了初始化,看類名可以翻譯成程序生命周期初始化,到這裡我們對該類就找不到調用者或者使用者了,是以不得不百度一下,發現有人說這個類是在

AndroidManifest.xml

中聲明的,在建構APK過程中,AS會将多個子產品的

AndroidManifest.xml

合并到一起,是以檢視build目錄,具體路徑為

build/intermediates/bundle_manifest/debug/processDebugManifest/bundle-manifest/AndroidManifest.xml

,果真在裡面:

到這裡整個Lifecycle初始化的過程就結束了。

4. 總結

經過上面的源碼分析,我們可以大概給整個Lifecycle元件分為三部分:

4.1 Lifecycle的初始化

4.2  Lifecycle的狀态改變及狀态分發

可以檢視下面的時序圖:

用fragment怎麼引入setcontentview_3. Jetpack源碼解析用Lifecycles管理生命周期1. 背景2. 基礎3. 源碼分析4. 總結5. 參考連結:

4.3 Lifecycle解析生命周期

我們聲明的MyObserver中的方法都是帶有注解的,檢視

OnLifecycleEvent

注解修飾的方法會通過反射的方式擷取,并且儲存在

ClassesInfoCache

中,然後在生命周期發生改變的時候再找到對應 Event 的方法,通過反射來調用方法。

5. 參考連結:

https://juejin.im/post/5cd81634e51d453af7192b87#heading-10

https://yuqirong.me/2018/07/15/Android%20Architecture%20Component%E4%B9%8BLifecycle%E8%A7%A3%E6%9E%90/

推薦閱讀

Android Jetpack - 使用 WorkManager 管理背景任務

用fragment怎麼引入setcontentview_3. Jetpack源碼解析用Lifecycles管理生命周期1. 背景2. 基礎3. 源碼分析4. 總結5. 參考連結:

掃一掃 關注我的公衆号 如果你想要跟大家分享你的文章,歡迎投稿~

繼續閱讀