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元件
中通過兩個枚舉類來跟蹤其關聯元件的生命周期:
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
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的狀态改變及狀态分發
可以檢視下面的時序圖:
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 管理背景任務
掃一掃 關注我的公衆号 如果你想要跟大家分享你的文章,歡迎投稿~