系列文章
【背上Jetpack】Jetpack 主要組件的依賴及傳遞關(guān)系
【背上Jetpack】AdroidX下使用Activity和Fragment的變化
【背上Jetpack之Fragment】你真的會(huì)用Fragment嗎?Fragment常見問(wèn)題以及androidx下Fragment的使用新姿勢(shì)
【背上Jetpack之Fragment】從源碼角度看 Fragment 生命周期 AndroidX Fragment1.2.2源碼分析
【背上Jetpack之OnBackPressedDispatcher】Fragment 返回棧預(yù)備篇
【背上Jetpack之Fragment】從源碼的角度看Fragment 返回棧 附多返回棧demo
【背上Jetpack】絕不丟失的狀態(tài) androidx SaveState ViewModel-SaveState 分析
【背上Jetpack之ViewModel】即使您不使用MVVM也要了解ViewModel ——ViewModel 的職能邊界
前言
Android 中有一個(gè)比較重要的概念:「生命周期」。剛畢業(yè)去面試,總會(huì)被問(wèn)到「四大組件的生命周期」這類的問(wèn)題。17年的 IO 大會(huì)上,Google 推出了 Lifecycle-Aware Components(生命周期感知組件),幫助開發(fā)者組織更好,更輕量,易于維護(hù)的代碼
本文介紹 Lifecycle 的職責(zé)以及簡(jiǎn)單分析 lifecycle 如何感知 activity 和 fragment ,幫助您對(duì) Lifecycle 有一個(gè)感性的認(rèn)識(shí)
萬(wàn)物基于 Lifecycle
手動(dòng)管理生命周期的痛苦你不懂
魯迅曾說(shuō)過(guò):萬(wàn)物基于 Lifecycle
哦不對(duì)
Android 中的視圖控制器就有這么多生命周期的情況,所以處理好生命周期十分重要,否則會(huì)導(dǎo)致內(nèi)存泄漏甚至是程序崩潰。這里引用 官方文檔 的例子
class MyLocationListener {
public MyLocationListener(Context context, Callback callback) {
// ...
}
void start() {
// 連接系統(tǒng)的定位服務(wù)
}
void stop() {
// 與系統(tǒng)的定位服務(wù)斷開連接
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
@Override
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, (location) -> {
// 更新 UI
});
}
@Override
public void onStart() {
super.onStart();
myLocationListener.start();
//管理其他需要響應(yīng) activity 生命周期的組件
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
//管理其他需要響應(yīng) activity 生命周期的組件
}
}
此示例看起來(lái)不錯(cuò),在實(shí)際的應(yīng)用程序中,您仍然會(huì)響應(yīng)生命周期的當(dāng)前狀態(tài)而進(jìn)行過(guò)多的調(diào)用來(lái)管理 UI 和其他組件。 管理多個(gè)組件會(huì)在生命周期方法中放置大量代碼,例如 onStart() 和 onStop(),這使它們難以維護(hù)
而且,不能保證組件在 activity 或 fragment 停止之前就已啟動(dòng)。 如果我們需要執(zhí)行長(zhǎng)時(shí)間運(yùn)行的操作(例如onStart() 中的某些配置檢查),則可能會(huì)導(dǎo)致爭(zhēng)用情況,其中onStop() 方法在 onStart() 之前完成,從而使組件的生存期超過(guò)了所需的生存期。
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, location -> {
// 更新 UI
});
}
@Override
public void onStart() {
super.onStart();
Util.checkUserStatus(result -> {
// 如果在 activity 停止后調(diào)用此回調(diào)怎么辦?
if (result) {
myLocationListener.start();
}
});
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
}
}
如果有所有的組件,都能感知外部的生命周期,能在相應(yīng)的時(shí)機(jī)釋放資源,并且在錯(cuò)過(guò)生命周期時(shí)能及時(shí)叫停異步的任務(wù)就好了,
我們不妨先思考一下,如果實(shí)現(xiàn)這樣的想法,應(yīng)該如何做
按照慣例的思考
首先我們先來(lái)整理一下我們的需求
- 內(nèi)部組件能夠感知外部的生命周期
- 能夠統(tǒng)一地管理,做到一處修改,處處生效
- 能夠及時(shí)叫停錯(cuò)過(guò)的任務(wù)
針對(duì)需求1,可以用觀察者模式,內(nèi)部組件能夠在外部生命周期變化時(shí)做出相應(yīng)
針對(duì)需求2,可以將依賴組件的代碼移出生命周期方法內(nèi),然后移入組件本身,這樣只需修改組件內(nèi)部邏輯即可
針對(duì)需求3,可以在合適的時(shí)機(jī)移除觀察者
觀察者模式
關(guān)于開發(fā)者模式,我第一次比較詳細(xì)的了解是在 扔物線 的 給 Android 開發(fā)者的 RxJava 詳解。
觀察者模式面向的需求是:A 對(duì)象(觀察者)對(duì) B 對(duì)象(被觀察者)的某種變化高度敏感,需要在 B 變化的一瞬間做出反應(yīng)。舉個(gè)例子,新聞里喜聞樂(lè)見的警察抓小偷,警察需要在小偷伸手作案的時(shí)候?qū)嵤┳ゲ?。在這個(gè)例子里,警察是觀察者,小偷是被觀察者,警察需要時(shí)刻盯著小偷的一舉一動(dòng),才能保證不會(huì)漏過(guò)任何瞬間。程序的觀察者模式和這種真正的『觀察』略有不同,觀察者不需要時(shí)刻盯著被觀察者(例如 A 不需要每過(guò) 2ms 就檢查一次 B 的狀態(tài)),而是采用注冊(cè)(Register)或者稱為訂閱(Subscribe)的方式,告訴被觀察者:我需要你的某某狀態(tài),你要在它變化的時(shí)候通知我。 Android 開發(fā)中一個(gè)比較典型的例子是點(diǎn)擊監(jiān)聽器
OnClickListener。對(duì)設(shè)置OnClickListener來(lái)說(shuō),View是被觀察者,OnClickListener是觀察者,二者通過(guò)setOnClickListener()方法達(dá)成訂閱關(guān)系。訂閱之后用戶點(diǎn)擊按鈕的瞬間,Android Framework 就會(huì)將點(diǎn)擊事件發(fā)送給已經(jīng)注冊(cè)的OnClickListener。采取這樣被動(dòng)的觀察方式,既省去了反復(fù)檢索狀態(tài)的資源消耗,也能夠得到最高的反饋速度。當(dāng)然,這也得益于我們可以隨意定制自己程序中的觀察者和被觀察者,而警察叔叔明顯無(wú)法要求小偷『你在作案的時(shí)候務(wù)必通知我』。
OnClickListener 的模式大致如下圖:
上述描述及圖片均來(lái)自 給 Android 開發(fā)者的 RxJava 詳解
因此在生命周期組件的生命周期發(fā)生變化時(shí)告訴觀察者,內(nèi)部組件即可感知外部的生命周期
引入 Lifecycle 后
public class MyObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void connectListener() {
...
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void disconnectListener() {
...
}
}
myLifecycleOwner.getLifecycle().addObserver(new MyObserver());
源碼結(jié)構(gòu)
這是 Lifecycle 的結(jié)構(gòu),抽象類,其內(nèi)部有兩個(gè)枚舉,分別代表著「事件」和「狀態(tài)」,此外還有三個(gè)方法,添加/移除觀察者,獲取當(dāng)前狀態(tài)
注意,這里 State 中的枚舉順序是有意義的,后文詳細(xì)介紹
其實(shí)現(xiàn)類為 LifecycleRegistry ,可以處理多個(gè)觀察者
其內(nèi)部持有當(dāng)前的狀態(tài) mState ,LifecycleOwner 以及觀察者的自定義列表,同時(shí)重寫了父類的添加/刪除觀察者的方法
LifecycleOwner ,具有 Android 的生命周期,定制組件可以使用這些事件來(lái)處理生命周期更改,而無(wú)需在 Activity 或 Fragment 中實(shí)現(xiàn)任何代碼
LifecycleObserver ,將一個(gè)類標(biāo)記為 LifecycleObserver。 它沒(méi)有任何方法,而是依賴于 OnLifecycleEvent 注解的方法
LifecycleEventObserver ,可以接收任何生命周期更改并將其分派給接收方。
如果一個(gè)類實(shí)現(xiàn)此接口并同時(shí)使用 OnLifecycleEvent,則注解將被忽略
DefaultLifecycleObserver ,用于監(jiān)聽 LifecycleOwner 狀態(tài)更改的回調(diào)接口。
如果一個(gè)類同時(shí)實(shí)現(xiàn)了此接口和 LifecycleEventObserver,則將首先調(diào)用DefaultLifecycleObserver 的方法,然后再調(diào)用LifecycleEventObserver.onStateChanged(LifecycleOwner,Lifecycle.Event)
注意:使用 DefaultLifecycleObserver 需引入
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
簡(jiǎn)單的源碼分析
activity 生命周期處理
首先我們還是來(lái)看 androidx.activity.ComponentActivity ,這個(gè)類我們這個(gè)系列的文章里提到多次,第一次提及是在 【背上Jetpack】絕不丟失的狀態(tài) androidx SaveState ViewModel-SaveState 分析 ,感興趣的小伙伴可以看看。
其實(shí)現(xiàn)的接口大多數(shù)我們都已經(jīng)探討過(guò)了,今天我們來(lái)看看 LifecycleOwner
ActivityResultCaller 為 activity 1.2.0-alpha02 推出的,旨在統(tǒng)一 onActivityResult ,這里暫時(shí)不討論它
既然實(shí)現(xiàn)了 LifecycleOwner 接口,必定重寫 getLifecycle() 方法
// androidx.activity.ComponentActivity.java
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
其返回的 Lifecycle 為 實(shí)現(xiàn)類 LifecycleRegistry 的實(shí)例
而 activity 操作生命周期是通過(guò) ReportFragment 處理的
// androidx.activity.ComponentActivity.java
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
//...
}
// ReportFragment
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
// api 29 及以上 直接注冊(cè)正確的生命周期回調(diào)
activity.registerActivityLifecycleCallbacks(
new LifecycleCallbacks());
}
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
// ReportFragment.java
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
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);
}
}
}
private void dispatch(@NonNull Lifecycle.Event event) {
if (Build.VERSION.SDK_INT < 29) {
dispatch(getActivity(), event);
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
dispatch(Lifecycle.Event.ON_RESUME);
}
@Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}
@Override
public void onStop() {
super.onStop();
dispatch(Lifecycle.Event.ON_STOP);
}
@Override
public void onDestroy() {
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);
}
// LifecycleCallbacks
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityPostCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
dispatch(activity, Lifecycle.Event.ON_CREATE);
}
@Override
public void onActivityPostStarted(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_START);
}
@Override
public void onActivityPostResumed(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_RESUME);
}
@Override
public void onActivityPrePaused(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_PAUSE);
}
@Override
public void onActivityPreStopped(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_STOP);
}
@Override
public void onActivityPreDestroyed(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_DESTROY);
}
//...
}
在 activity 的 onCreate 方法中,調(diào)用了 ReportFragment 中的靜態(tài)方法 injectIfNeededIn() 。而其內(nèi)部,如果 api 29 及以上的設(shè)備上直接注冊(cè)正確的生命周期回調(diào),低版本通過(guò)啟動(dòng) ReportFragment ,借助 fragment 各個(gè)生命周期來(lái)處理生命周期回調(diào)
fragment 生命周期處理
在 fragment 內(nèi)部,每個(gè)生命周期節(jié)點(diǎn)調(diào)用 handleLifecycleEvent 方法
// Fragment.java
public Fragment() {
initLifecycle();
}
private void initLifecycle() {
mLifecycleRegistry = new LifecycleRegistry(this);
}
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
void performCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState);
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
void performStart() {
onStart();
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
void performResume() {
onResume();
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}
void performPause() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
onPause();
}
void performStop() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
onStop();
}
void performDestroy() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
onDestroy();
}
Lifecycle State 大小比較
Lifecycle.State 中有一個(gè) isAtLeast 方法,用于判斷當(dāng)前狀態(tài)是否不小于傳入的狀態(tài)
// Lifecycle.State
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
枚舉的 compareTo 方法其實(shí)是比較的枚舉聲明的順序
而 State 的順序?yàn)?DESTROYED -> INITIALIZED -> CREATED -> STARTED -> RESUMED
如果傳入的 state 為 STARTED,則當(dāng)前狀態(tài)為 STARTED 或 RESUMED 時(shí)返回 true ,否則返回 false
LiveData 篇會(huì)用到這個(gè)知識(shí)點(diǎn)
關(guān)于我
我是 Fly_with24