Lifecycle:生命周期感知型組件的基礎(chǔ) —— Jetpack 系列(1)

請(qǐng)點(diǎn)贊,你的點(diǎn)贊對(duì)我意義重大,滿足下我的虛榮心。

?? Hi,我是小彭。本文已收錄到 GitHub · Android-NoteBook 中。這里有 Android 進(jìn)階成長(zhǎng)知識(shí)體系,有志同道合的朋友,跟我一起成長(zhǎng)。

前言

  • 生命周期是 Activity 的核心特性之一,也是 Android 視圖開發(fā)無(wú)法規(guī)避的重要問(wèn)題。 為了更加健壯地處理生命周期問(wèn)題,Google 的解決方案是將生命周期定義為一套標(biāo)準(zhǔn)的行為模式,即 Lifecycle 框架。 這種方式不僅簡(jiǎn)化了在 Activity / Fragment 等生命周期宿主中分發(fā)生命周期事件的復(fù)雜度,還提供了自定義生命周期宿主的標(biāo)準(zhǔn)模板。
  • Lifecycle 是多個(gè) Jetpack 組件的基礎(chǔ),例如我們熟悉的 LiveData 就是以 Lifecycle 為基礎(chǔ)實(shí)現(xiàn)的生命周期感知型數(shù)據(jù)容器,因此我們選擇將 Lifecycle 放在 Jetpack 系列的第一篇。

從這篇文章開始,我將帶你全面掌握 Jetpack 組件,系列文章:

一、架構(gòu)組件:

二、其他:

  • 13、AppStartup:輕量級(jí)初始化框架
  • 14、DataStore:新一代鍵值對(duì)存儲(chǔ)方案
  • 15、Room:ORM 數(shù)據(jù)庫(kù)訪問(wèn)框架
  • 16、WindowManager:加強(qiáng)對(duì)多窗口模式的支持
  • 17、WorkManager:加強(qiáng)對(duì)后臺(tái)任務(wù)的支持
  • 18、Compose:新一代視圖開發(fā)方案

1. 認(rèn)識(shí) Lifecycle

1.1 為什么要使用 Lifecycle?

Lifecycle 的主要作用是簡(jiǎn)化實(shí)現(xiàn)生命周期感知型組件的復(fù)雜度。 在傳統(tǒng)的方式中,需要手動(dòng)從外部宿主(如 Activity、Fragment 或自定義宿主)中將生命周期事件分發(fā)到功能組件內(nèi)部,這勢(shì)必會(huì)造成宿主代碼復(fù)雜度增加。例如:

MyActivity.kt

// Activity 宿主
class MyActivity : AppCompatActivity() {

    private val myWorker = MyWorker()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 分發(fā)生命周期事件
        myWorker.init()
    }
        
    override fun onStart(){
        super.onStart()
        // 分發(fā)生命周期事件
        myWorker.onStart()
    }

    override fun onStop() {
        super.onStop()
        // 分發(fā)生命周期事件
        myWorker.onStop()
    }
}

而使用 Lifecycle 組件后,能夠?qū)⒎职l(fā)宿主生命周期事件的方法遷移到功能組件內(nèi)部,宿主不再需要直接參與調(diào)整功能組件的生命周期。例如:

MyActivity.kt

// Activity 宿主
class MyActivity : AppCompatActivity() {

    private val myWorker = MyWorker()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 注冊(cè)觀察者
        lifecycle.addObserver(myWorker)
    }
}

MyWorker.kt

class MyWorker : LifecycleEventObserver {

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        // 分發(fā)生命周期事件
        when (event) {
            Lifecycle.Event.ON_CREATE -> init()
            Lifecycle.Event.ON_START -> onStart()
            Lifecycle.Event.ON_STOP -> onStop()
        }
    }

    private fun init() {
        ...
    }

    private fun onStart() {
        ...
    }

    private fun onStop() {
        ...
    }
}

1.2 Lifecycle 的設(shè)計(jì)思路

Lifecycle 整體上采用了觀察者模式,核心的 API 是 LifecycleObserver 和 LifecycleOwner:

  • LifecycleObserver: 觀察者 API;
  • LifecycleOwner: 被觀察者 API,生命周期宿主需要實(shí)現(xiàn)該接口,并將生命周期狀態(tài)分發(fā) Lifecycle,從而間接分發(fā)給被觀察者;
  • Lifecycle: 定義了生命周期的標(biāo)準(zhǔn)行為模式,屬于 Lifecycle 框架的核心類,另外框架還提供了一個(gè)默認(rèn)實(shí)現(xiàn) LifecycleRegistry。

LifecycleObserver.java

public interface LifecycleObserver {
}

LifecycleOwner.java

public interface LifecycleOwner {
    @NonNull
    Lifecycle getLifecycle();
}

1.3 Lifecycle 的使用方法

  • 添加依賴: 在 build.gradle 中添加 Lifecycle 依賴,需要注意區(qū)分過(guò)時(shí)的方式:

模塊 build.gradle

// 過(guò)時(shí)方式(lifecycle-extensions 不再維護(hù))
implementation "androidx.lifecycle:lifecycle-extensions:2.4.0"

// 目前的方式:
def lifecycle_version = "2.5.0"

// Lifecycle 核心類
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
// Lifecycle 注解處理器(用于處理 @OnLifecycleEvent 注解)
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// 應(yīng)用進(jìn)程級(jí)別 Lifecycle
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
  • 注冊(cè)觀察者: Lifecycle 通過(guò) addObserver(LifecycleObserver) 接口注冊(cè)觀察者,支持通過(guò)注解或非注解的方式注冊(cè)觀察者,共分為 3 種:

    • 1、LifecycleObserver(注解方式 ,不推薦): 在這個(gè)場(chǎng)景使用注解處理有種殺雞用牛刀的嫌疑,并沒(méi)有比其他兩種方式有優(yōu)勢(shì)。注解方式存在注解處理過(guò)程,并且如果在依賴時(shí)遺漏注解處理器的話,還會(huì)退化為使用反射回調(diào),因此不推薦使用。
    lifecycle.addObserver(object : LifecycleObserver {
    
        @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
        fun create() = {}
    
        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        fun start() = {}
    
        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
        fun resume() = {}
    
        @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
        fun pause() = {}
    
        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        fun stop() = {}
    
        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        fun destroy() = {}
    })
    
    • 2、LifecycleEventObserver(非注解方式,推薦)
    lifecycle.addObserver(object : LifecycleEventObserver {
        override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
            when (event) {
                ON_CREATE -> {}
                ON_START -> {}
                ON_RESUME -> {}
                ON_PAUSE -> {}
                ON_STOP -> {}
                ON_DESTROY -> {}
                ON_ANY -> {}
            }
        }
    })
    
    • 3、DefaultLifecycleObserver(非注解方式,推薦)
    // DefaultLifecycleObserver 是 FullLifecycleObserver 接口的空實(shí)現(xiàn)
    lifecycle.addObserver(object : DefaultLifecycleObserver {
        
        override fun onCreate(owner: LifecycleOwner) {}
    
        override fun onStart(owner: LifecycleOwner) {}
    
        override fun onResume(owner: LifecycleOwner) {}
    
        override fun onPause(owner: LifecycleOwner) {}
    
        override fun onStop(owner: LifecycleOwner) {}
    
        override fun onDestroy(owner: LifecycleOwner) {}
    })
    

注意: Lifecycle 內(nèi)部會(huì)禁止一個(gè)觀察者注冊(cè)到多個(gè)宿主上。這很好理解,要是綁定了多個(gè)宿主的話,Lifecycle 就不知道以哪個(gè)宿主的生命周期為準(zhǔn)了。

1.4 預(yù)定義的宿主

目前,Android 預(yù)定義的 Lifecycle 宿主有 3 個(gè):Activity、Fragment 和應(yīng)用進(jìn)程級(jí)別的宿主 ProcessLifecycleOwner:

  • 1、Activity(具體實(shí)現(xiàn)在 androidx.activity.ComponentActivity)
  • 2、Fragment
  • 3、ProcessLifecycleOwner

前兩個(gè)宿主大家都很熟悉了,第 3 個(gè)宿主 ProcessLifecycleOwner 則提供整個(gè)應(yīng)用進(jìn)程級(jí)別 Activity 的生命周期,能夠支持非毫秒級(jí)別精度監(jiān)聽(tīng)?wèi)?yīng)用前后臺(tái)切換的場(chǎng)景。

  • Lifecycle.Event.ON_CREATE: 在應(yīng)用進(jìn)程啟動(dòng)時(shí)分發(fā),只會(huì)分發(fā)一次;
  • Lifecycle.Event.ON_START:在應(yīng)用進(jìn)程進(jìn)入前臺(tái)(STARTED)時(shí)分發(fā),可能分發(fā)多次;
  • Lifecycle.Event.ON_RESUME:在應(yīng)用進(jìn)程進(jìn)入前臺(tái)(RESUMED)時(shí)分發(fā),可能分發(fā)多次;
  • Lifecycle.Event.ON_PAUSE:在應(yīng)用退出前臺(tái)(PAUSED)時(shí)分發(fā),可能分發(fā)多次;
  • Lifecycle.Event.ON_STOP:在應(yīng)用退出前臺(tái)(STOPPED)時(shí)分發(fā),可能分發(fā)多次;
  • Lifecycle.EVENT.ON_DESTROY:注意,不會(huì)被分發(fā)。

使用示例

ProcessLifecycleOwner.get().lifecycle.addObserver(object: LifecycleEventObserver{
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        ...
    }
})

1.5 自定義宿主

觀察者必須綁定到宿主 LifecycleOwner 上,你可以使用系統(tǒng)預(yù)定義的宿主,或根據(jù)需要自定義宿主。主要步驟是實(shí)現(xiàn) LifecycleOwner 并在內(nèi)部將生命周期事件分發(fā)給調(diào)度器 LifecycleRegistry。模板如下:

LifecycleOwner.java

public interface LifecycleOwner {
    Lifecycle getLifecycle();
}

MyLifecycleOwner.kt

/**
 * 自定義宿主模板
 */
class MyLifecycleOwner : LifecycleOwner {

    private val mLifecycleRegistry = LifecycleRegistry(this)

    override fun getLifecycle() = mLifecycleRegistry

    fun create() {
        // 并將生命周期狀態(tài)分發(fā)給被觀察者
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
    }

    fun start() {
        // 并將生命周期狀態(tài)分發(fā)給被觀察者
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
    }

    fun stop() {
        // 并將生命周期狀態(tài)分發(fā)給被觀察者
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
    }
    ...
}

2. Lifecycle 實(shí)現(xiàn)原理分析

2.1 注冊(cè)觀察者的執(zhí)行過(guò)程

Lifecycle#addObserver() 最終會(huì)分發(fā)到調(diào)度器 LifecycleRegistry 中,其中會(huì)將觀察者和觀察者持有的狀態(tài)包裝為一個(gè)節(jié)點(diǎn),并且在注冊(cè)時(shí)將觀察者狀態(tài)同步推進(jìn)到與宿主相同的狀態(tài)中。

LifecycleRegistry.java

private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();

private State mState;

@Override
public void addObserver(LifecycleObserver observer) {
    // 觀察者的初始狀態(tài):要么是 DESTROYED,要么是 INITIALIZED,確保觀察者可以介紹到完整的事件流
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    ...

    // 將觀察者推進(jìn)到宿主最新的狀態(tài)
    State targetState = calculateTargetState(observer);
    while ((statefulObserver.mState.compareTo(targetState) < 0 && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
        popParentState();
        // mState / subling may have been changed recalculate
        targetState = calculateTargetState(observer);
    }
        ...
}

@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
    mObserverMap.remove(observer);
}

// ObserverWithState:觀察者及其觀察狀態(tài)
static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        // 用適配器包裝觀察者,實(shí)現(xiàn)對(duì)不同形式觀察者的統(tǒng)一分發(fā)
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }
}

2.2 Lifecycle 如何適配不同類型的觀察者

為了適配上面提到的不同類型的觀察者,LifecycleRegistry 還為它們提供了一個(gè)適配層:非注解的方式會(huì)包裝為一個(gè) LifecycleEventObserver 的適配器對(duì)象,對(duì)于注解的方式,如果項(xiàng)目中引入了 annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" ,會(huì)在編譯時(shí)生成工具類 MyObserver_LifecycleAdapter ,否則會(huì)使用反射回調(diào)注解方法。

LifecycleRegistry.java

// ObserverWithState:觀察者及其觀察狀態(tài)
static class ObserverWithState {
    State mState;
    // 適配器
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        // 用適配器包裝觀察者,實(shí)現(xiàn)對(duì)不同形式觀察者的統(tǒng)一分發(fā)
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }

    void dispatchEvent(LifecycleOwner owner, Event event) {
        // 通過(guò)事件獲得下一個(gè)狀態(tài)
        State newState = getStateAfter(event);
        mState = min(mState, newState);
        // 回調(diào) onStateChanged() 方法
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

Lifecycling.java

@NonNull
static LifecycleEventObserver lifecycleEventObserver(Object object) {
    boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
    boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
    // 1. 觀察者同時(shí)實(shí)現(xiàn) LifecycleEventObserver 和 FullLifecycleObserver
    if (isLifecycleEventObserver && isFullLifecycleObserver) {
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, (LifecycleEventObserver) object);
    }
    // 2. 觀察者只實(shí)現(xiàn) FullLifecycleObserver
    if (isFullLifecycleObserver) {
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
    }
    // 3. 觀察者只實(shí)現(xiàn) LifecycleEventObserver
    if (isLifecycleEventObserver) {
        return (LifecycleEventObserver) object;
    }

    // 4. 觀察者使用注解方式:
    final Class<?> klass = object.getClass();
    int type = getObserverConstructorType(klass);
    if (type == GENERATED_CALLBACK) {
        // APT 自動(dòng)生成的 MyObserver_LifecycleAdapter
        List<Constructor<? extends GeneratedAdapter>> 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);
    }
    // 反射調(diào)用
    return new ReflectiveGenericLifecycleObserver(object);
}

FullLifecycleObserverAdapter.java

class FullLifecycleObserverAdapter implements LifecycleEventObserver {
    private final FullLifecycleObserver mFullLifecycleObserver;
    private final LifecycleEventObserver mLifecycleEventObserver;

    FullLifecycleObserverAdapter(FullLifecycleObserver fullLifecycleObserver,LifecycleEventObserver lifecycleEventObserver) {
        mFullLifecycleObserver = fullLifecycleObserver;
        mLifecycleEventObserver = lifecycleEventObserver;
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
        // 分發(fā)到 mFullLifecycleObserver 和 mLifecycleEventObserver
    }
}

2.3 Lifecycle 如何感知 Activity 生命周期

宿主的生命周期事件需要分發(fā)到調(diào)度器 LifecycleRegistry 中,在高版本有直接觀察 Activity 生命周期的 API,而在低版本使用無(wú)界面的 Fragment 間接觀察 Activity 的生命周期。

androidx.activity.ComponentActivity.java

public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner ...{
    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        ReportFragment.injectIfNeededIn(this);
        ...
    }
}

ReportFragment.java

// 空白 Fragment
public class ReportFragment extends Fragment {
    public static void injectIfNeededIn(Activity activity) {
        if (Build.VERSION.SDK_INT >= 29) {
            // 在高版本有直接觀察 Activity 生命周期的 API
            activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
        }
        // 在低版本使用無(wú)界面的 Fragment 間接觀察 Activity 的生命周期
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            // Hopefully, we are the first to make a transaction.
            manager.executePendingTransactions();
        }
    }

    // 從 registerActivityLifecycleCallbacks() 或 Fragment 回調(diào)回來(lái)
    static void dispatch(Activity activity, Lifecycle.Event event) {
        ...
        // 分發(fā)聲明周期事件
        activity.getLifecycle().handleLifecycleEvent(event);
    }
}

2.4 Lifecycle 分發(fā)生命周期事件的過(guò)程

當(dāng)宿主的生命周期發(fā)生變化時(shí),會(huì)分發(fā)到 LifecycleRegistry#handleLifecycleEvent(Lifecycle.Event),將觀察者的狀態(tài)回調(diào)到最新的狀態(tài)上。

Untitled.png

LifecycleRegistry.java

private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =new FastSafeIterableMap<>();

private final WeakReference<LifecycleOwner> mLifecycleOwner;

public LifecycleRegistry(@NonNull LifecycleOwner provider) {
    mLifecycleOwner = new WeakReference<>(provider);
    mState = INITIALIZED;
}

// 分發(fā)生命周期事件
public void handleLifecycleEvent(Lifecycle.Event event) {
    // 通過(guò)事件獲得下一個(gè)狀態(tài)
    State next = getStateAfter(event);
    // 執(zhí)行狀態(tài)轉(zhuǎn)移
    moveToState(next);
}

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

private void sync() {
    // isSynced() 判斷所有觀察者狀態(tài)是否同步到最新?tīng)顟B(tài)
    while (!isSynced()) {
        mNewEventOccurred = false;
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            // 生命周期回退,最終調(diào)用 ObserverWithState#dispatchEvent() 分發(fā)事件
            backwardPass(lifecycleOwner);
        }
        Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null && mState.compareTo(newest.getValue().mState) > 0) {
            // 生命周期前進(jìn),最終調(diào)用 ObserverWithState#dispatchEvent() 分發(fā)事件
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

3. Lifecycle 實(shí)踐案例

3.1 使用 Lifecycle 解決 Dialog 內(nèi)存泄漏

在 Activity 結(jié)束時(shí),如果 Activity 上還存在未關(guān)閉的 Dialog,則會(huì)導(dǎo)致內(nèi)存泄漏:

WindowLeaked: Activtiy MainActivity has leaked window DecorView@dfxxxx[MainActivity] thas was originally added here

解決方法:

  • 方法 1:在 Activity#onDestroy() 中手動(dòng)調(diào)用 Dialog#dismiss();
  • 方法 2:替換為 DialogFragment,內(nèi)部會(huì)在 Fragment#onDestroyView() 時(shí)關(guān)閉 Dialog;
  • 方法 3:自定義 BaseDialog,使用 Lifecycle 監(jiān)聽(tīng)宿主 DESTROYED 生命周期關(guān)閉 Dialog:

BaseDialog.kt

class BaseDialog(context: Context) : Dialog(context), LifecycleEventObserver {
    init {
        if (context is ComponentActivity) {
            context.lifecycle.addObserver(this)
        }
    }

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        if (Lifecycle.Event.ON_DESTROY == event) {
            if (isShowing) {
                dismiss()
            }
        }
    }
}

3.2 生命周期感知型協(xié)程

Lifecycle 也加強(qiáng)了對(duì) Kotlin 協(xié)程的支持 LifecycleCoroutineScope,我們可以構(gòu)造出與生命周期相關(guān)聯(lián)的協(xié)程作用域,主要支持 2 個(gè)特性:

  • 1、在宿主消亡(DESTROYED)時(shí),自動(dòng)取消協(xié)程;
  • 2、在宿主離開指定生命周期狀態(tài)時(shí)掛起,在宿主重新進(jìn)入指定生命周期狀態(tài)時(shí)恢復(fù)協(xié)程(例如 launchWhenResumed)。

使用示例

// 示例 1
lifecycleScope.launch {

}
// 示例 2(內(nèi)部等價(jià)于示例 3)
lifecycleScope.launchWhenResumed {

}
// 示例 3
lifecycleScope.launch {
    whenResumed {

    }
}

1、自動(dòng)取消協(xié)程實(shí)現(xiàn)原理分析: 核心在于 LifecycleCoroutineScopeImpl 中,內(nèi)部在初始化時(shí)會(huì)注冊(cè)一個(gè)觀察者到宿主生命周期上,并在宿主進(jìn)入 DESTROYED 時(shí)取消(cancel)協(xié)程。

LifecycleOwner.kt

// 基于 LifecycleOwner 的擴(kuò)展函數(shù)
public val LifecycleOwner.lifecycleScope: LifecycleCoroutineScope
    get() = lifecycle.coroutineScope

Lifecycle.kt

public val Lifecycle.coroutineScope: LifecycleCoroutineScope
    get() {
        // 已簡(jiǎn)化
        val newScope = LifecycleCoroutineScopeImpl(
            this,
            SupervisorJob() + Dispatchers.Main.immediate
        )
        newScope.register()
        return newScope
    }

public abstract class LifecycleCoroutineScope internal constructor() : CoroutineScope {
    internal abstract val lifecycle: Lifecycle

    ...

    // 開啟協(xié)程再調(diào)用 whenResumed
    public fun launchWhenResumed(block: suspend CoroutineScope.() -> Unit): Job = launch {
        lifecycle.whenResumed(block)
    }
}

// 實(shí)現(xiàn)類
internal class LifecycleCoroutineScopeImpl(
    override val lifecycle: Lifecycle,
    override val coroutineContext: CoroutineContext
) : LifecycleCoroutineScope(), LifecycleEventObserver {
    init {
        // 立即取消協(xié)程
        if (lifecycle.currentState == Lifecycle.State.DESTROYED) {
            coroutineContext.cancel()
        }
    }

    fun register() {
        // 綁定宿主生命周期
        launch(Dispatchers.Main.immediate) {
            if (lifecycle.currentState >= Lifecycle.State.INITIALIZED) {
                lifecycle.addObserver(this@LifecycleCoroutineScopeImpl)
            } else {
                coroutineContext.cancel()
            }
        }
    }

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        // 分發(fā)宿主生命周期事件
        if (lifecycle.currentState <= Lifecycle.State.DESTROYED) {
            // 取消協(xié)程
            lifecycle.removeObserver(this)
            coroutineContext.cancel()
        }
    }
}

2、關(guān)聯(lián)指定生命周期實(shí)現(xiàn)原理分析: 實(shí)現(xiàn)原理也是類似的,launchWhenResumed() 內(nèi)部在 LifecycleContro 中注冊(cè)觀察者,最終通過(guò)協(xié)程調(diào)度器 PausingDispatcher 掛起(pause)或恢復(fù)(resume)協(xié)程。

PausingDispatcher.kt

public suspend fun <T> LifecycleOwner.whenResumed(block: suspend CoroutineScope.() -> T): T =
    lifecycle.whenResumed(block)

public suspend fun <T> Lifecycle.whenResumed(block: suspend CoroutineScope.() -> T): T {
    return whenStateAtLeast(Lifecycle.State.RESUMED, block)
}

public suspend fun <T> Lifecycle.whenStateAtLeast(
    minState: Lifecycle.State,
    block: suspend CoroutineScope.() -> T
): T = withContext(Dispatchers.Main.immediate) {
    val job = coroutineContext[Job] ?: error("when[State] methods should have a parent job")
    // 分發(fā)器,內(nèi)部持有一個(gè)分發(fā)隊(duì)列,用于支持暫停協(xié)程
    val dispatcher = PausingDispatcher()
    val controller = LifecycleController(this@whenStateAtLeast, minState, dispatcher.dispatchQueue, job)
    try {
        withContext(dispatcher, block)
    } finally {
        controller.finish()
    }
}

LifecycleController.kt

@MainThread
internal class LifecycleController(
    private val lifecycle: Lifecycle,
    private val minState: Lifecycle.State,
    private val dispatchQueue: DispatchQueue,
    parentJob: Job
) {
    private val observer = LifecycleEventObserver { source, _ ->
        // 分發(fā)宿主生命周期事件
        if (source.lifecycle.currentState == Lifecycle.State.DESTROYED) {
            // 取消協(xié)程
            parentJob.cancel()
            lifecycle.removeObserver(observer)
            dispatchQueue.finish()
        } else if (source.lifecycle.currentState < minState) {
            // 暫停協(xié)程
            dispatchQueue.pause()
        } else {
            // 恢復(fù)協(xié)程
            dispatchQueue.resume()
        }
    }

    init {
        // 直接取消協(xié)程
        if (lifecycle.currentState == Lifecycle.State.DESTROYED) {
            // 取消協(xié)程
            parentJob.cancel()
            lifecycle.removeObserver(observer)
            dispatchQueue.finish()
        } else {
            lifecycle.addObserver(observer)
        }
    }
}

3.3 安全地觀察 Flow 數(shù)據(jù)流

我們知道,Kotlin Flow 不具備生命周期感知的能力(當(dāng)然了,F(xiàn)low 是 Kotlin 生態(tài)的組件,不是僅針對(duì) Android 生態(tài)的組件),那么 Flow 觀察者如何保證在安全的生命周期訂閱數(shù)據(jù)呢?

  • 方法 1:使用生命周期感知型協(xié)程(不推薦)
  • 方法 2:使用 Flow#flowWithLifecycle() API(推薦)

具體分析在 4、Flow:LiveData 的替代方案 這篇文章里都講過(guò),這里不重復(fù)。


4. 總結(jié)

到這里,Jetpack 中最基礎(chǔ)的 Lifecycle 組件就講完了,下幾篇文章我們將討論基于 Lifecycle 實(shí)現(xiàn)的其他 Jetpack 組件,你知道是什么嗎?關(guān)注我,帶你了解更多。


參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容