硬核講解 Jetpack 之 LifeCycle 源碼篇

前一篇 硬核講解 Jetpack 之 LifeCycle 使用篇 主要介紹了 LifeCycle 存在的意義,基本和進階的使用方法。今天話不多說,直接開始擼源碼。

本文基於我手裡的 android_9.0.0_r45 源碼,所有相關源碼包括註釋都上傳到了我的 Github ,可以直接 clone 下來對照文章查看。

LifeCycle 三劍客

在正式閱讀源碼之前,很有必要先介紹幾個名詞,LifecycleOwnerLifecycleObserverLifecycle

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

Lifecycle

getLifecycle

()

{

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

State

calculateTargetState

(

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

State

getStateAfter

(

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(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

; } /<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 ,流程如下。

  1. ReportFragment 調用 dispatch(Lifecycle.Event.ON_PAUSE) ,分發 ON_PAUSE 事
  2. 調用 LifecycleRegistry.handleLifecycleEvent() 方法,參數是 ON_PAUSE
  3. getStateAfter() 得到要同步到的狀態是 STARTED ,並賦給 mState,接著調用 moveToState()
  4. moveToState(Lifecycle.State.STARTED) 中調用 sync() 方法同步
  5. 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()))) { Event

event

= downEvent(observer.mState); pushParentState(getStateAfter(

event

)); observer.dispatchEvent(lifecycleOwner,

event

); popParentState(); } } } /<code>

二者唯一的區別就是獲取要分發的事件,一個是 upEvent() ,一個是 downEvent() 。

upEvent() 是獲取 state 升級所需要經歷的事件,downEvent() 是獲取 state 降級所需要經歷的事件。

<code>

private

static

Event

upEvent

(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

Event

downEvent

(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 的關係,官網給出了一張圖,如下所所示:


硬核講解 Jetpack 之 LifeCycle 源碼篇


但我不得不說,畫的的確有點抽象,其實應該換個畫法。再來一張我在 這裡 看到的一張圖:

硬核講解 Jetpack 之 LifeCycle 源碼篇

狀態之間的事件事件之後的狀態狀態之間的大小 ,是不是有種一目瞭然的感覺?理解這幅圖很重要,可以說搞不清 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

GenericLifecycleObserver

getCallback

(

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

type

= resolveObserverCallbackType(klass); sCallbackCache.put(klass,

type

);

return

type

; }

private

static

int resolveObserverCallbackType(Class> klass) {

if

(klass.getCanonicalName() ==

null

) {

return

REFLECTIVE_CALLBACK; } Constructor

extends

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) { OnLifecycleEvent

annotation

= 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超能解析-生命週期的那些事兒


分享到:


相關文章: