前一篇 硬核講解 Jetpack 之 LifeCycle 使用篇 主要介紹了 LifeCycle 存在的意義,基本和進階的使用方法。今天話不多說,直接開始擼源碼。
本文基於我手裡的 android_9.0.0_r45 源碼,所有相關源碼包括註釋都上傳到了我的 Github ,可以直接 clone 下來對照文章查看。
LifeCycle 三劍客
在正式閱讀源碼之前,很有必要先介紹幾個名詞,LifecycleOwner ,LifecycleObserver,Lifecycle 。
LifecycleOwner 是一個接口 , 接口通常用來聲明具備某種能力。LifecycleOwner 的能力就是具有生命週期。典型的生命週期組件有 Activity 和 Fragment 。當然,我們也可以自定義生命週期組件。LifecycleOwner 提供了 getLifecycle() 方法來獲取其 Lifecycle 對象。
<code>public
interface
LifecycleOwner
{Lifecycle
getLifecycle
()
; } /<code>
LifecycleObserver 是生命週期觀察者,它是一個空接口。它沒有任何方法,依賴 OnLifecycleEvent 註解來接收生命週期回調。
<code>public
interface
LifecycleObserver
{ } /<code>
生命週期組件 和 生命週期觀察者 都有了,Lifecycle 就是它們之間的橋樑。
Lifecycle 是具體的生命週期對象,每個 LifecycleOwner 都會持有 Lifecycle 。通過 Lifecycle 我們可以獲取當前生命週期狀態,添加/刪除 生命週期觀察者等等。
Lifecycle 內部定義了兩個枚舉類,Event 和 State 。Event 表示生命週期事件,與 LifecycleOwner 的生命週期事件是相對應的。
<code>public
enum Event { ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY, ON_ANY } /<code>
ON_ANY 比較特殊,它表示任意生命週期事件。為什麼要設計 ON_ANY 呢?其實我也不知道,暫時還沒發現它的用處。
另一個枚舉類 State 表示生命週期狀態。
<code>public
enum
State { DESTROYED, INITIALIZED, CREATED, STARTED, RESUMED;public
boolean
isAtLeast( State state) {return
compareTo(state) >=0
; } } /<code>
State 可能相對比較難以理解,特別是其中枚舉值的順序。這裡先不詳細解讀,但是務必記住這幾個枚舉值的順序,DESTROYED —— INITIALIZED —— CREATED —— STARTED ——RESUMED,這個對於後面源碼的理解特別重要。
簡單梳理一下三劍客的關係。生命週期組件 LifecycleOwner 在進入特定的生命週期後,發送特定的生命週期事件 Event ,通知 Lifcycle 進入特定的 State ,進而回調生命週期觀察者 LifeCycleObserver 的指定方法。
從 addObserver() 下手
面對源碼無從下手的話,我們就從 Lifecycle 的基本使用入手。
<code>lifecycle
.addObserver
(LocationUtil
( )) /<code>
lifecycle 其實就是 getLifecycle()方法,只是在 Kotlin中被 簡寫了。getLifecycle() 是接口 LifecycleOwner 的方法。而 AppCompatActivity 並沒有直接實現 LifecycleOwner,它的父類 FragmentActivity 也沒有,在它的爺爺類 ComponentActivity 中才找到 LifecycleOwner 的蹤影,看一下接口的實現。
<code>
public
LifecyclegetLifecycle
()
{return
mLifecycleRegistry; } /<code>
mLifecycleRegistry 是 LifecycleRegistry 對象,LifecycleRegistry 是 LifeCycle 的實現類。那麼這裡的 LifecycleRegistry 就是我們的生命週期對象了。來看一下它的 addObserver() 方法。
<code>> LifecycleRegistry.java ......private
FastSafeIterableMap mObserverMap =new
FastSafeIterableMap<>();private
State mState;public
void
addObserver( LifecycleObserver observer) { State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED; ObserverWithState statefulObserver =new
ObserverWithState(observer, initialState); ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);if
(previous !=null
) {return
; } LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if
(lifecycleOwner ==null
) {return
; }boolean
isReentrance = mAddingObserverCounter !=0
|| mHandlinengEvent; State targetState = calculateTargetState(observer); mAddingObserverCounter++;while
((statefulObserver.mState.compareTo(targetState)0
&& mObserverMap.contains(observer))) { pushParentState(statefulObserver.mState); statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState)); popParentState(); targetState = calculateTargetState(observer); }if
(!isReentrance) { sync(); } mAddingObserverCounter--; } /<code>
這裡面要注意兩個問題。第一個問題是生命週期的 "倒灌問題" ,這是我從 LiveData 那裡借來的一次詞。具體是什麼問題呢?來舉一個例子,即使你在 onResume( ) 中調用 addObserver( ) 方法來添加觀察者,觀察者依然可以依次接收到 onCreate 和 onStart 事件 ,最終同步到 targetState 。這個 targetState 是通過 calculateTargetState(observer)方法計算出來的。
<code>private
StatecalculateTargetState
(LifecycleObserver observer
) { Entry previous = mObserverMap.ceil(observer); State siblingState = previous !=null
? previous.getValue().mState :null
; State parentState = !mParentStates.isEmpty() ? mParentStates.get
(mParentStates.size() -1
) :null
;return
min(min(mState, siblingState), parentState); } /<code>
我們可以添加多個生命週期觀察者,這時候就得注意維護它們的狀態。每次添加新的觀察者的初始狀態是 INITIALIZED ,需要把它同步到當前生命週期狀態,確切的說,同步到一個不大於當前狀態的 targetState 。從源碼中的計算方式也有所體現,targetState 是 當前狀態 mState,
mObserverMap 中最後一個觀察者的狀態 ,有重入情況下 parentState 的狀態 這三者中的最小值。為什麼要取這個最小值呢?我是這麼理解的,當有新的生命週期事件時,需要將 mObserverMap 中的所有觀察者都同步到新的同一狀態,這個同步過程可能尚未完成,所以新加入的觀察者只能先同步到最小狀態。注意在 addObserver 方法的 while 循環中,新的觀察者每改變一次生命週期,都會調用 calculateTargetState() 重新計算 targetState 。
最終的穩定狀態下,沒有生命週期切換,沒有添加新的觀察者,mObserverMap 中的所有觀察者應該處於同一個生命週期狀態。
誰來分發生命週期事件?
觀察者已經添加完成了,那麼如何將生命週期的變化通知觀察者呢?
再回到 ComponentActivity ,你會發現裡面並沒有重寫所有的生命週期函數。唯一讓人可疑的就只有 onCreate() 當中的一行代碼。
<code>@Override
protected void onCreate(@Nullable
Bundle savedInstanceState) {super
.onCreate
(savedInstanceState);mSavedStateRegistryController
.performRestore
(savedInstanceState);ReportFragment
.injectIfNeededIn
(this);if
(mContentLayoutId !=0
) {setContentView
(mContentLayoutId); } } /<code>
這裡的 ReportFragment 就是問題的答案。追進 injectIfNeededIn() 方法。
<code>public
static
void
injectIfNeededIn
(Activity activity
) { android.app.FragmentManager manager = activity.getFragmentManager();if
(manager.findFragmentByTag(REPORT_FRAGMENT_TAG) ==null
) { manager.beginTransaction().add
(new
ReportFragment(), REPORT_FRAGMENT_TAG).commit(); manager.executePendingTransactions(); } } /<code>
這裡向 Activity 注入了一個沒有頁面的 Fragment 。這就讓我想到了一些動態權限庫也是這個套路,通過注入 Fragment 來代理權限請求。不出意外,ReportFragment 才是真正分發生命週期的地方。
<code>public
void
onActivityCreated
(Bundle savedInstanceState)
{super
.onActivityCreated(savedInstanceState); dispatchCreate(mProcessListener); dispatch(Lifecycle.Event.ON_CREATE); }public
void
onStart
()
{super
.onStart(); dispatchStart(mProcessListener); dispatch(Lifecycle.Event.ON_START); }public
void
onResume
()
{super
.onResume(); dispatchResume(mProcessListener); dispatch(Lifecycle.Event.ON_RESUME); }public
void
onPause
()
{super
.onPause(); dispatch(Lifecycle.Event.ON_PAUSE); }public
void
onStop
()
{super
.onStop(); dispatch(Lifecycle.Event.ON_STOP); }public
void
onDestroy
()
{super
.onDestroy(); dispatch(Lifecycle.Event.ON_DESTROY); mProcessListener =null
; } /<code>
mProcessListener 是處理應用進程生命週期的,暫時不去管它。
先看一下 dispatch() 方法。
<code>private
void
dispatch
(Lifecycle.Event
event
) { Activity activity = getActivity();if
(activity instanceof LifecycleRegistryOwner) { ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event
);return
; }if
(activity instanceof LifecycleOwner) { Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();if
(lifecycle instanceof LifecycleRegistry) { ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event
); } } } /<code>
在ReportFragment 的各個生命週期函數中通過 dispatch() 方法來分發生命週期事件, 然後調用 LifecycleRegistry 的 handleLifecycleEvent()方法來處理 。為了方便後面的代碼理解,這裡假定 現在要經歷從 onStart() 同步到 onResume() 的過程,即handleLifecycleEvent() 方法中的參數是 ON_RESUME 。
<code>public
void
handleLifecycleEvent
(@NonNull Lifecycle.Event
event
) { State next = getStateAfter(event
); moveToState(next); } /<code>
getStateAfter() 的作用是根據 Event 獲取事件之後處於的狀態 ,並通知觀察者同步到此生命週期狀態。
<code>static
StategetStateAfter
(Event
event
) {switch
(event
) {case
ON_CREATE:case
ON_STOP:return
CREATED;case
ON_START:case
ON_PAUSE:return
STARTED;case
ON_RESUME:return
RESUMED;case
ON_DESTROY:return
DESTROYED;case
ON_ANY:break
; }throw
new
IllegalArgumentException("Unexpected event value "
+event
); } /<code>
參數是 ON_RESUME ,所以需要同步到的狀態是 RESUMED 。接下來看看 moveToState() 方法的邏輯。
<code>private void moveToState(Statenext
) {if
(mState ==next
) {return
; } mState =next
;if
(mHandlingEvent||
mAddingObserverCounter !=0
) { mNewEventOccurred =true
;//
we will figure out what todo
on upper level.return
; } mHandlingEvent =true
; sync(); mHandlingEvent =false
; } /<code>
首先將要同步到的生命週期狀態賦給當前生命週期狀態 mState ,此時 mState 的值就是 RESUMED 。然後調用 sync() 方法同步所有觀察者的狀態。
<code>private
void
sync
() { LifecycleOwner lifecycleOwner = 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
;if
(mState.compareTo(mObserverMap.eldest().getValue().mState)0
) { backwardPass(lifecycleOwner); } Entry newest = mObserverMap.newest();if
(!mNewEventOccurred && newest !=null
&& mState.compareTo(newest.getValue().mState) >0
) { forwardPass(lifecycleOwner); } } mNewEventOccurred =false
; } /<code>
這裡會比較 mState 和 mObserverMap 中觀察者的 State 值,判斷是需要向前還是向後同步狀態。現在 mState 的值是 RESUMED , 而觀察者還停留在上一狀態 STARTED ,所以觀察者的狀態都得往前挪一步,這裡調用的是 forwardPass() 方法。
<code>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(); } } } /<code>
forwardPass() 會同步 mObserverMap 中的所有觀察者到指定生命週期狀態,如果跨度比較大,會依次分發中間狀態。分發生命週期事件最終依賴 ObserverWithState 的 dispatchEvent() 方法。
這裡先暫停存檔一下,不繼續往下追源碼。上面假定的場景是 ON_START 到 ON_RESUME 的過程。現在假定另一個場景,我直接按下 Home 鍵返回桌面,當前 Activity 的生命週期從onResumed 到 onPaused ,流程如下。
- ReportFragment 調用 dispatch(Lifecycle.Event.ON_PAUSE) ,分發 ON_PAUSE 事
- 調用 LifecycleRegistry.handleLifecycleEvent() 方法,參數是 ON_PAUSE
- getStateAfter() 得到要同步到的狀態是 STARTED ,並賦給 mState,接著調用 moveToState()
- moveToState(Lifecycle.State.STARTED) 中調用 sync() 方法同步
- sync() 方法中,mState 的值是 STARTED ,而 mObserverMap中觀察者的狀態都是 RESUMED 。所以觀察者們都需要往後挪一步,這調用的就是 backwardPass() 方法。
backwardPass() 方法其實和 forwardPass() 差不多。
<code>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()))) { Eventevent
= downEvent(observer.mState); pushParentState(getStateAfter(event
)); observer.dispatchEvent(lifecycleOwner,event
); popParentState(); } } } /<code>
二者唯一的區別就是獲取要分發的事件,一個是 upEvent() ,一個是 downEvent() 。
upEvent() 是獲取 state 升級所需要經歷的事件,downEvent() 是獲取 state 降級所需要經歷的事件。
<code>private
static
EventupEvent
(State state)
{switch
(state) {case
INITIALIZED:case
DESTROYED:return
ON_CREATE;case
CREATED:return
ON_START;case
STARTED:return
ON_RESUME;case
RESUMED:throw
new
IllegalArgumentException(); }throw
new
IllegalArgumentException("Unexpected state value "
+ state); }private
static
EventdownEvent
(State state)
{switch
(state) {case
INITIALIZED:throw
new
IllegalArgumentException();case
CREATED:return
ON_DESTROY;case
STARTED:return
ON_STOP;case
RESUMED:return
ON_PAUSE;case
DESTROYED:throw
new
IllegalArgumentException(); }throw
new
IllegalArgumentException("Unexpected state value "
+ state); } /<code>
從 STARTED 到 RESUMED 需要升級,upEvent(STARTED) 的返回值是 ON_RESUME 。 從 RESUMED 到 STARTED 需要降級,downEvent(RESUMED)的返回值是 ON_PAUSE 。
看到這不知道你有沒有一點懵,State 和 Event 的關係我也摸索了很長一段時間才理清楚。首先還記得 State 的枚舉值順序嗎?
<code>DESTROYED
—— INITIALIZED —— CREATED —— STARTED —— RESUMED /<code>
DESTROYED 最小,RESUMED 最大 。onResume 進入到 onPause階段最後分發的生命週期事件的確是 ON_PAUSE ,但是將觀察者的狀態置為了 STARTED 。這是為什麼呢?
關於 State 和 Event 的關係,官網給出了一張圖,如下所所示:
但我不得不說,畫的的確有點抽象,其實應該換個畫法。再來一張我在 這裡 看到的一張圖:
狀態之間的事件,事件之後的狀態,狀態之間的大小 ,是不是有種一目瞭然的感覺?理解這幅圖很重要,可以說搞不清 Event 和 State 的關係,就看不懂 Lifecycle 的源碼。
誰來回調你的註解方法 ?
再讀取剛才的暫停存檔,同步 Observer 生命週期的 sync() 方法最終會調用 ObserverWithState 的 dispatchEvent() 方法。
<code>static
class
ObserverWithState
{ State mState; GenericLifecycleObserver mLifecycleObserver; ObserverWithState(LifecycleObserver observer, State initialState) { mLifecycleObserver = Lifecycling.getCallback(observer); mState = initialState; }void
dispatchEvent
(LifecycleOwner owner, Event
event
) { State newState = getStateAfter(event
); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner,event
); mState = newState; } } /<code>
mLifecycleObserver 通過 Lifecycling.getCallback() 方法賦值。
<code>@NonNull
static
GenericLifecycleObservergetCallback
(Object
object
) {if
(object
instanceof FullLifecycleObserver) {return
new
FullLifecycleObserverAdapter((FullLifecycleObserver)object
); }if
(object
instanceof GenericLifecycleObserver) {return
(GenericLifecycleObserver)object
; } final Class> klass =object
.getClass();int
type = getObserverConstructorType(klass);if
(type == GENERATED_CALLBACK) { List> constructors = sClassToAdapters.get
(klass);if
(constructors.size() ==1
) { GeneratedAdapter generatedAdapter = createGeneratedAdapter( constructors.get
(0
),object
);return
new
SingleGeneratedAdapterObserver(generatedAdapter); } GeneratedAdapter[] adapters =new
GeneratedAdapter[constructors.size()];for
(int
i =0
; i < constructors.size(); i++) { adapters[i] = createGeneratedAdapter(constructors.get
(i),object
); }return
new
CompositeGeneratedAdaptersObserver(adapters); }return
new
ReflectiveGenericLifecycleObserver(object
); } /<code>
如果使用的是 DefaultLifecycleObserver ,而 DefaultLifecycleObserver 又是繼承 FullLifecycleObserver 的,所以這裡會返回 FullLifecycleObserverAdapter 。
如果只是普通的 LifecycleObserver ,那麼就需要通過 getObserverConstructorType() 方法判斷使用的是註解還是反射。
<code>private
static
int getObserverConstructorType(Class> klass) {if
(sCallbackCache.containsKey(klass)) {return
sCallbackCache.get(klass); } inttype
= resolveObserverCallbackType(klass); sCallbackCache.put(klass,type
);return
type
; }private
static
int resolveObserverCallbackType(Class> klass) {if
(klass.getCanonicalName() ==null
) {return
REFLECTIVE_CALLBACK; } Constructorextends
GeneratedAdapter>constructor
= generatedConstructor(klass
);if
(constructor
!= null) { sClassToAdapters.put(klass, Collections .extends GeneratedAdapter>>singletonList(constructor
));return
GENERATED_CALLBACK; }boolean
hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass);if
(hasLifecycleMethods) {return
REFLECTIVE_CALLBACK; } Class> superclass = klass.getSuperclass(); Listextends GeneratedAdapter>> adapterConstructors =null
;if
(isLifecycleParent(superclass)) {if
(getObserverConstructorType(superclass) == REFLECTIVE_CALLBACK) {return
REFLECTIVE_CALLBACK; } adapterConstructors =new
ArrayList<>(sClassToAdapters.get(superclass)); }for
(Class> intrface : klass.getInterfaces()) {if
(!isLifecycleParent(intrface)) {continue
; }if
(getObserverConstructorType(intrface) == REFLECTIVE_CALLBACK) {return
REFLECTIVE_CALLBACK; }if
(adapterConstructors ==null
) { adapterConstructors =new
ArrayList<>(); } adapterConstructors.addAll(sClassToAdapters.get(intrface)); }if
(adapterConstructors !=null
) { sClassToAdapters.put(klass, adapterConstructors);return
GENERATED_CALLBACK; }return
REFLECTIVE_CALLBACK; } /<code>
注意其中的 hasLifecycleMethods() 方法。
<code>boolean hasLifecycleMethods(Class klass) {if
(mHasLifecycleMethods.containsKey(klass)) {return
mHasLifecycleMethods.get
(klass); } Method[] methods = getDeclaredMethods(klass);for
(Method method : methods) { OnLifecycleEventannotation
= method.getAnnotation(OnLifecycleEvent.
class
);if
(annotation
!=null
) { createInfo(klass, methods);return
true
; } } mHasLifecycleMethods.put(klass,false
);return
false
; } /<code>
這裡會去尋找 OnLifecycleEvent 註解。所以我們通過 OnLifecycleEvent 註解實現的 MyObserver 的類型是 REFLECTIVE_CALLBACK ,表示使用反射調用。注意另一個類型 GENERATED_CALLBACK 表示使用註解生成的代碼,而不是反射。
所以,所以,Lifecycle 可以選擇使用 apt 編譯期生成代碼來避免使用運行時反射,以優化性能?好像還真是這麼一回事。這就讓我想到了 EventBus 的索引加速 默認也是關閉的。看吧,這就是閱讀源碼的好處,總能發現自己的知識盲區。添加下列依賴,來提速 LifeCycle 吧 !
<code>kapt
"androidx.lifecycle:lifecycle-compiler:
$lifecycle_version
" /<code>
為了方便解析,還是回到反射調用上來。
我們自己定義的在普通的觀察者調用的是 ReflectiveGenericLifecycleObserver.onStateChanged() 。
<code>class
ReflectiveGenericLifecycleObserver
implements
GenericLifecycleObserver
{private
final
Object mWrapped;private
final
CallbackInfo mInfo; ReflectiveGenericLifecycleObserver(Object wrapped) { mWrapped = wrapped; mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass()); }public
void
onStateChanged
(LifecycleOwner source, Event event)
{ mInfo.invokeCallbacks(source, event, mWrapped); } } /<code>
再追進 ClassesInfoCache.CallbackInfo.invokeCallbacks() 方法。
<code>void
invokeCallbacks
(LifecycleOwner source, Lifecycle.Event
event
, Object target) { invokeMethodsForEvent(mEventToHandlers.get
(event
), source,event
, target); invokeMethodsForEvent(mEventToHandlers.get
(Lifecycle.Event.ON_ANY), source,event
, target); }private
static
void
invokeMethodsForEvent
(List handlers, LifecycleOwner source, Lifecycle.Event
event
, Object mWrapped) {if
(handlers !=null
) {for
(int
i = handlers.size() -1
; i >=0
; i--) { handlers.get
(i).invokeCallback(source,event
, mWrapped); } } }void
invokeCallback
(LifecycleOwner source, Lifecycle.Event
event
, Object target) {try
{switch
(mCallType) {case
CALL_TYPE_NO_ARG: mMethod.invoke(target);break
;case
CALL_TYPE_PROVIDER: mMethod.invoke(target, source);break
;case
CALL_TYPE_PROVIDER_WITH_EVENT: mMethod.invoke(target, source,event
);break
; } }catch
(InvocationTargetException e) {throw
new
RuntimeException("Failed to call observer method"
, e.getCause()); }catch
(IllegalAccessException e) {throw
new
RuntimeException(e); } } /<code>
其實就很簡單了,反射調用 OnLifecycleEvent 註解標記的生命週期回調方法。
Wait For More
本想再接著分析進程生命週期 ProcessLifecycleOwner 和 Lifecycle 的協程使用相關源碼,可是文章篇幅有點過長了,就留到下一篇吧,敬請期待!
參考和推薦
下面幾篇文章同樣優秀,直接仔細研讀,推薦給大家。
- Android架構之美-Lifecycle
- Jetpack和LifeCycle(三)
- Android-Lifecycle超能解析-生命週期的那些事兒