請點贊,你的點贊對我意義重大叨襟,滿足下我的虛榮心繁扎。
?? Hi,我是小彭糊闽。本文已收錄到 GitHub · Android-NoteBook 中梳玫。這里有 Android 進階成長知識體系,有志同道合的朋友右犹,跟我一起成長提澎。
前言
- 生命周期是 Activity 的核心特性之一,也是 Android 視圖開發(fā)無法規(guī)避的重要問題念链。 為了更加健壯地處理生命周期問題虱朵,Google 的解決方案是將生命周期定義為一套標準的行為模式,即 Lifecycle 框架钓账。 這種方式不僅簡化了在 Activity / Fragment 等生命周期宿主中分發(fā)生命周期事件的復(fù)雜度碴犬,還提供了自定義生命周期宿主的標準模板。
- Lifecycle 是多個 Jetpack 組件的基礎(chǔ)梆暮,例如我們熟悉的 LiveData 就是以 Lifecycle 為基礎(chǔ)實現(xiàn)的生命周期感知型數(shù)據(jù)容器服协,因此我們選擇將 Lifecycle 放在 Jetpack 系列的第一篇。
從這篇文章開始啦粹,我將帶你全面掌握 Jetpack 組件偿荷,系列文章:
一窘游、架構(gòu)組件:
- 1、Lifecycle:生命周期感知型組件的基礎(chǔ)(本文)
- 2跳纳、LiveData:生命周期感知型數(shù)據(jù)容器
- 3忍饰、ViewModel:數(shù)據(jù)驅(qū)動型界面控制器
- 4、Flow:LiveData 的替代方案
- 5寺庄、從 MVC 到 MVP艾蓝、MVVM、MVI:Android UI 架構(gòu)演進
- 6斗塘、ViewBinding:新一代視圖綁定方案
- 7赢织、Fragment:模塊化的微型 Activity
- 8、RecyclerView:可復(fù)用型列表視圖
- 9馍盟、Navigation:單 Activity 多 Fragment 的導(dǎo)航方案
- 10于置、Dagger2:從 Dagger2 到 Hilt 玩轉(zhuǎn)依賴注入(一)
- 11、Hilt:從 Dagger2 到 Hilt 玩轉(zhuǎn)依賴注入(二)
- 12贞岭、OnBackPressedDispatcher:處理回退事件的新姿勢
二八毯、其他:
- 13、AppStartup:輕量級初始化框架
- 14瞄桨、DataStore:新一代鍵值對存儲方案
- 15话速、Room:ORM 數(shù)據(jù)庫訪問框架
- 16、WindowManager:加強對多窗口模式的支持
- 17讲婚、WorkManager:加強對后臺任務(wù)的支持
- 18尿孔、Compose:新一代視圖開發(fā)方案
1. 認識 Lifecycle
1.1 為什么要使用 Lifecycle俊柔?
Lifecycle 的主要作用是簡化實現(xiàn)生命周期感知型組件的復(fù)雜度筹麸。 在傳統(tǒng)的方式中,需要手動從外部宿主(如 Activity雏婶、Fragment 或自定義宿主)中將生命周期事件分發(fā)到功能組件內(nèi)部物赶,這勢必會造成宿主代碼復(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)
// 注冊觀察者
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è)計思路
Lifecycle 整體上采用了觀察者模式错维,核心的 API 是 LifecycleObserver 和 LifecycleOwner:
- LifecycleObserver: 觀察者 API奖地;
- LifecycleOwner: 被觀察者 API,生命周期宿主需要實現(xiàn)該接口赋焕,并將生命周期狀態(tài)分發(fā) Lifecycle参歹,從而間接分發(fā)給被觀察者;
- Lifecycle: 定義了生命周期的標準行為模式隆判,屬于 Lifecycle 框架的核心類犬庇,另外框架還提供了一個默認實現(xiàn) LifecycleRegistry僧界。
LifecycleObserver.java
public interface LifecycleObserver {
}
LifecycleOwner.java
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
1.3 Lifecycle 的使用方法
- 添加依賴: 在 build.gradle 中添加 Lifecycle 依賴,需要注意區(qū)分過時的方式:
模塊 build.gradle
// 過時方式(lifecycle-extensions 不再維護)
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)用進程級別 Lifecycle
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
-
注冊觀察者: Lifecycle 通過 addObserver(LifecycleObserver) 接口注冊觀察者臭挽,支持通過注解或非注解的方式注冊觀察者捂襟,共分為 3 種:
-
1、LifecycleObserver(注解方式 欢峰,不推薦):在這個場景使用注解處理有種殺雞用牛刀的嫌疑葬荷,并沒有比其他兩種方式有優(yōu)勢。注解方式存在注解處理過程赤赊,并且如果在依賴時遺漏注解處理器的話闯狱,還會退化為使用反射回調(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 接口的空實現(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)部會禁止一個觀察者注冊到多個宿主上。這很好理解波俄,要是綁定了多個宿主的話晨逝,Lifecycle 就不知道以哪個宿主的生命周期為準了。
1.4 預(yù)定義的宿主
目前懦铺,Android 預(yù)定義的 Lifecycle 宿主有 3 個:Activity捉貌、Fragment 和應(yīng)用進程級別的宿主 ProcessLifecycleOwner:
- 1、Activity(具體實現(xiàn)在 androidx.activity.ComponentActivity)
- 2冬念、Fragment
- 3趁窃、ProcessLifecycleOwner
前兩個宿主大家都很熟悉了,第 3 個宿主 ProcessLifecycleOwner 則提供整個應(yīng)用進程級別 Activity 的生命周期急前,能夠支持非毫秒級別精度監(jiān)聽應(yīng)用前后臺切換的場景醒陆。
- Lifecycle.Event.ON_CREATE: 在應(yīng)用進程啟動時分發(fā),只會分發(fā)一次裆针;
- Lifecycle.Event.ON_START:在應(yīng)用進程進入前臺(STARTED)時分發(fā)刨摩,可能分發(fā)多次;
- Lifecycle.Event.ON_RESUME:在應(yīng)用進程進入前臺(RESUMED)時分發(fā)世吨,可能分發(fā)多次澡刹;
- Lifecycle.Event.ON_PAUSE:在應(yīng)用退出前臺(PAUSED)時分發(fā),可能分發(fā)多次耘婚;
- Lifecycle.Event.ON_STOP:在應(yīng)用退出前臺(STOPPED)時分發(fā)罢浇,可能分發(fā)多次;
- Lifecycle.EVENT.ON_DESTROY:注意边篮,不會被分發(fā)己莺。
使用示例
ProcessLifecycleOwner.get().lifecycle.addObserver(object: LifecycleEventObserver{
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
...
}
})
1.5 自定義宿主
觀察者必須綁定到宿主 LifecycleOwner 上奏甫,你可以使用系統(tǒng)預(yù)定義的宿主,或根據(jù)需要自定義宿主凌受。主要步驟是實現(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 實現(xiàn)原理分析
2.1 注冊觀察者的執(zhí)行過程
Lifecycle#addObserver() 最終會分發(fā)到調(diào)度器 LifecycleRegistry 中,其中會將觀察者和觀察者持有的狀態(tài)包裝為一個節(jié)點胜蛉,并且在注冊時將觀察者狀態(tài)同步推進到與宿主相同的狀態(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);
...
// 將觀察者推進到宿主最新的狀態(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) {
// 用適配器包裝觀察者领突,實現(xiàn)對不同形式觀察者的統(tǒng)一分發(fā)
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
}
2.2 Lifecycle 如何適配不同類型的觀察者
為了適配上面提到的不同類型的觀察者,LifecycleRegistry 還為它們提供了一個適配層:非注解的方式會包裝為一個 LifecycleEventObserver 的適配器對象案怯,對于注解的方式君旦,如果項目中引入了 annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
,會在編譯時生成工具類 MyObserver_LifecycleAdapter
嘲碱,否則會使用反射回調(diào)注解方法金砍。
LifecycleRegistry.java
// ObserverWithState:觀察者及其觀察狀態(tài)
static class ObserverWithState {
State mState;
// 適配器
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
// 用適配器包裝觀察者,實現(xiàn)對不同形式觀察者的統(tǒng)一分發(fā)
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
// 通過事件獲得下一個狀態(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. 觀察者同時實現(xiàn) LifecycleEventObserver 和 FullLifecycleObserver
if (isLifecycleEventObserver && isFullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, (LifecycleEventObserver) object);
}
// 2. 觀察者只實現(xiàn) FullLifecycleObserver
if (isFullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
}
// 3. 觀察者只實現(xiàn) LifecycleEventObserver
if (isLifecycleEventObserver) {
return (LifecycleEventObserver) object;
}
// 4. 觀察者使用注解方式:
final Class<?> klass = object.getClass();
int type = getObserverConstructorType(klass);
if (type == GENERATED_CALLBACK) {
// APT 自動生成的 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恕稠,而在低版本使用無界面的 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());
}
// 在低版本使用無界面的 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)回來
static void dispatch(Activity activity, Lifecycle.Event event) {
...
// 分發(fā)聲明周期事件
activity.getLifecycle().handleLifecycleEvent(event);
}
}
2.4 Lifecycle 分發(fā)生命周期事件的過程
當(dāng)宿主的生命周期發(fā)生變化時扶欣,會分發(fā)到 LifecycleRegistry#handleLifecycleEvent(Lifecycle.Event)
鹅巍,將觀察者的狀態(tài)回調(diào)到最新的狀態(tài)上。
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) {
// 通過事件獲得下一個狀態(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à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) {
// 生命周期前進骆捧,最終調(diào)用 ObserverWithState#dispatchEvent() 分發(fā)事件
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
3. Lifecycle 實踐案例
3.1 使用 Lifecycle 解決 Dialog 內(nèi)存泄漏
在 Activity 結(jié)束時,如果 Activity 上還存在未關(guān)閉的 Dialog术陶,則會導(dǎo)致內(nèi)存泄漏:
WindowLeaked: Activtiy MainActivity has leaked window DecorView@dfxxxx[MainActivity] thas was originally added here
解決方法:
- 方法 1:在 Activity#onDestroy() 中手動調(diào)用 Dialog#dismiss()凑懂;
- 方法 2:替換為 DialogFragment煤痕,內(nèi)部會在 Fragment#onDestroyView() 時關(guān)閉 Dialog梧宫;
- 方法 3:自定義 BaseDialog,使用 Lifecycle 監(jiān)聽宿主 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 也加強了對 Kotlin 協(xié)程的支持 LifecycleCoroutineScope摆碉,我們可以構(gòu)造出與生命周期相關(guān)聯(lián)的協(xié)程作用域塘匣,主要支持 2 個特性:
- 1、在宿主消亡(DESTROYED)時巷帝,自動取消協(xié)程忌卤;
- 2、在宿主離開指定生命周期狀態(tài)時掛起楞泼,在宿主重新進入指定生命周期狀態(tài)時恢復(fù)協(xié)程(例如 launchWhenResumed)驰徊。
使用示例
// 示例 1
lifecycleScope.launch {
}
// 示例 2(內(nèi)部等價于示例 3)
lifecycleScope.launchWhenResumed {
}
// 示例 3
lifecycleScope.launch {
whenResumed {
}
}
1笤闯、自動取消協(xié)程實現(xiàn)原理分析: 核心在于 LifecycleCoroutineScopeImpl 中,內(nèi)部在初始化時會注冊一個觀察者到宿主生命周期上棍厂,并在宿主進入 DESTROYED 時取消(cancel)協(xié)程颗味。
LifecycleOwner.kt
// 基于 LifecycleOwner 的擴展函數(shù)
public val LifecycleOwner.lifecycleScope: LifecycleCoroutineScope
get() = lifecycle.coroutineScope
Lifecycle.kt
public val Lifecycle.coroutineScope: LifecycleCoroutineScope
get() {
// 已簡化
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)
}
}
// 實現(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)指定生命周期實現(xiàn)原理分析: 實現(xiàn)原理也是類似的牺弹,launchWhenResumed() 內(nèi)部在 LifecycleContro 中注冊觀察者浦马,最終通過協(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)部持有一個分發(fā)隊列晶默,用于支持暫停協(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)的組件磺陡,不是僅針對 Android 生態(tài)的組件),那么 Flow 觀察者如何保證在安全的生命周期訂閱數(shù)據(jù)呢漠畜?
- 方法 1:使用生命周期感知型協(xié)程(不推薦)
- 方法 2:使用 Flow#flowWithLifecycle() API(推薦)
具體分析在 4仅政、Flow:LiveData 的替代方案 這篇文章里都講過,這里不重復(fù)盆驹。
4. 總結(jié)
到這里圆丹,Jetpack 中最基礎(chǔ)的 Lifecycle 組件就講完了,下幾篇文章我們將討論基于 Lifecycle 實現(xiàn)的其他 Jetpack 組件躯喇,你知道是什么嗎辫封?關(guān)注我,帶你了解更多廉丽。
參考資料
- 使用生命周期感知型組件處理生命周期 —— 官方文檔
- Lifecycle倦微,看完這次就真的懂了 —— g小志 著
- 使用 ProcessLifecycle 優(yōu)雅地監(jiān)聽應(yīng)用前后臺切換 —— Flywith24 著