Jetpack AAC 系列文章:
“終於懂了“系列:Jetpack AAC完整解析(一)Lifecycle 完全掌握!
“終於懂了“系列:Jetpack AAC完整解析(二)LiveData 完全掌握!
“終於懂了“系列:Jetpack AAC完整解析(三)ViewModel 完全掌握!
......
一、Android Jetpack 介紹
1.1 Jetpack是啥
官方定義如下:
Jetpack 是一個由多個庫組成的套件,可幫助開發者遵循最佳做法,減少樣板代碼並編寫可在各種 Android 版本和設備中一致運行的代碼,讓開發者精力集中編寫重要的代碼。
JetPack更多是一種概念和態度,它是谷歌開發的非Android Framework SDK自帶、但同時是Android開發必備的/推薦的SDK/開發規範合集。相當於Google把自己的Android生態重新整理了一番,確立了Android未來的開發大方向。
使用Jetpack有如下好處:
- 遵循最佳做法,Android Jetpack 組件採用最新的設計方法構建,具有向後兼容性,可以減少崩潰和內存泄露。
- 消除樣板代碼,Android Jetpack 可以管理各種繁瑣的 Activity(如後臺任務、導航和生命週期管理),以便您可以專注於打造出色的應用。
- 減少不一致,這些庫可在各種 Android 版本和設備中以一致的方式運作,助您降低複雜性。
Jetpack原意爲 噴氣揹包,Android背上Jetpack後就直衝雲霄,這很形象了~
也就是,Jetpack是幫助開發者高效開發應用的工具集。那麼這一工具包含了哪些內容呢?
1.2 Jetpack分類
分類如下圖(現在官網已經找不到這個圖了):
Android Jetpack 組件覆蓋以下 4 個方面:架構(Architecture)、基礎(Foundation)、行爲(Behavior) 、界面(UI)。
真正的精華主要是Architecture,全稱是Android Architecture Component(AAC), 即Android架構組件。
其包括比較成功的Lifecycle、LiveData、ViewModel,同時也是我們使用MVVM模式的最好框架工具,可以組合使用,也可以單獨使用。
以上基本都是官網的介紹,我們主要目標就是掌握AAC的組件,深入理解進而運用到MVVM架構中。
如題,我們學習Jetpack的重點就是AAC,這篇就從基礎的Lifecycle講起。
二、Lifecycle
Lifecycle,顧名思義,是用於幫助開發者管理Activity和Fragment 的生命週期,它是LiveData和ViewModel的基礎。下面就先介紹爲何及如何使用Lifecycle。
2.1 Lifecycle之前
官方文檔有個例子 來說明使用Lifecycle之前是如何生命週期管理的:
假設我們有一個在屏幕上顯示設備位置的 Activity。常見的實現可能如下所示:
class MyLocationListener {
public MyLocationListener(Context context, Callback callback) {
// ...
}
void start() {
// 連接系統定位服務
}
void stop() {
// 斷開系統定位服務
}
}
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();
// 管理其他需要響應activity生命週期的組件
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
// 管理其他需要響應activity生命週期的組件
}
}
雖然此示例看起來沒問題,但在真實的應用中,最終會有太多管理界面和其他組件的調用,以響應生命週期的當前狀態。管理多個組件會在生命週期方法(如 onStart() 和 onStop())中放置大量的代碼,這使得它們難以維護。
此外,無法保證組件會在 Activity 或 Fragment 停止之前啓動myLocationListener。在我們需要執行長時間運行的操作(如 onStart() 中的某種配置檢查)時尤其如此。在這種情況下,myLocationListener的onStop() 方法會在 onStart() 之前調用,這使得組件留存的時間比所需的時間要長,從而導致內次泄漏。如下:
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 -> {
//如果checkUserStatus耗時較長,在activity停止後纔回調,那麼myLocationListener啓動後就沒辦法走stop()方法了,
//又因爲myLocationListener持有activity,所以會造成內存泄漏。
if (result) {
myLocationListener.start();
}
});
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
}
}
即2個問題點:
- activity的生命週期內有大量管理組件的代碼,難以維護。
- 無法保證組件會在 Activity/Fragment停止後不執行啓動
Lifecycle庫 則可以 以彈性和隔離的方式解決這些問題。
2.2 Lifecycle的使用
Lifecycle是一個庫,也包含Lifecycle這樣一個類,Lifecycle類 用於存儲有關組件(如 Activity 或 Fragment)的生命週期狀態的信息,並允許其他對象觀察此狀態。
2.2.1 引入依賴
1、非androidX項目 引入:
implementation "android.arch.lifecycle:extensions:1.1.1"
添加這一句代碼就依賴瞭如下的庫:
2、androidX項目 引入:
如果項目已經依賴了AndroidX:
implementation 'androidx.appcompat:appcompat:1.2.0'
那麼我們就可以使用Lifecycle庫了,因爲appcompat依賴了androidx.fragment,而androidx.fragment下依賴了ViewModel和 LiveData,LiveData內部又依賴了Lifecycle。
如果想要單獨引入依賴,則如下:
在項目根目錄的build.gradle添加 google() 代碼庫,然後app的build.gradle引入依賴,官方給出的依賴如下:
//根目錄的 build.gradle
repositories {
google()
...
}
//app的build.gradle
dependencies {
def lifecycle_version = "2.2.0"
def arch_version = "2.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// 只有Lifecycles (不帶 ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// lifecycle註解處理器
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// 替換 - 如果使用Java8,就用這個替換上面的lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
//以下按需引入
// 可選 - 幫助實現Service的LifecycleOwner
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// 可選 - ProcessLifecycleOwner給整個 app進程 提供一個lifecycle
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// 可選 - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
// 可選 - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
}
看着有很多,實際上如果只使用Lifecycle,只需要引入lifecycle-runtime即可。但通常都是和 ViewModel、 LiveData 配套使用的,所以lifecycle-viewmodel、lifecycle-livedata 一般也會引入。
另外,lifecycle-process是給整個app進程提供一個lifecycle,會面也會提到。
2.2.2 使用方法
Lifecycle的使用很簡單:
- 1、生命週期擁有者 使用getLifecycle()獲取Lifecycle實例,然後代用addObserve()添加觀察者;
- 2、觀察者實現LifecycleObserver,方法上使用OnLifecycleEvent註解關注對應生命週期,生命週期觸發時就會執行對應方法;
2.2.2.1 基本使用
在Activity(或Fragment)中 一般用法如下:
public class LifecycleTestActivity extends AppCompatActivity {
private String TAG = "Lifecycle_Test";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lifecycle_test);
//Lifecycle 生命週期
getLifecycle().addObserver(new MyObserver());
Log.i(TAG, "onCreate: ");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume: ");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause: ");
}
}
Activity(或Fragment)是生命週期的擁有者,通過getLifecycle()方法獲取到生命週期Lifecycle對象,Lifecycle對象使用addObserver方法 給自己添加觀察者,即MyObserver對象。當Lifecycle的生命週期發生變化時,MyObserver就可以感知到。
MyObserver是如何使用生命週期的呢?看下MyObserver的實現:
public class MyObserver implements LifecycleObserver {
private String TAG = "Lifecycle_Test";
@OnLifecycleEvent(value = Lifecycle.Event.ON_RESUME)
public void connect(){
Log.i(TAG, "connect: ");
}
@OnLifecycleEvent(value = Lifecycle.Event.ON_PAUSE)
public void disConnect(){
Log.i(TAG, "disConnect: ");
}
}
首先MyObserver實現了接口LifecycleObserver,LifecycleObserver用於標記一個類是生命週期觀察者。
然後在connectListener()、disconnectListener()上 分別都加了@OnLifecycleEvent註解,且value分別是Lifecycle.Event.ON_RESUME、Lifecycle.Event.ON_PAUSE,這個效果就是:connectListener()會在ON_RESUME時執行,disconnectListener()會在ON_PAUSE時執行。
我們打開LifecycleTestActivity 然後退出,日誌打印如下:
2020-11-09 17:25:40.601 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: onCreate:
2020-11-09 17:25:40.605 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: onResume:
2020-11-09 17:25:40.605 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: connect:
2020-11-09 17:25:51.841 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: disConnect:
2020-11-09 17:25:51.841 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: onPause:
可見MyObserver的方法 確實是在對應關注的生命週期觸發時調用。 當然註解中的value你也寫成其它 你關注的任何一個生命週期,例如Lifecycle.Event.ON_DESTROY。
2.2.2.2 MVP架構中的使用
如果是 在MVP架構中,那麼就可以把presenter作爲觀察者:
public class LifecycleTestActivity extends AppCompatActivity implements IView {
private String TAG = "Lifecycle_Test";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lifecycle_test);
//Lifecycle 生命週期
// getLifecycle().addObserver(new MyObserver());
//MVP中使用Lifecycle
getLifecycle().addObserver(new MyPresenter(this));
Log.i(TAG, "onCreate: ");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume: ");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause: ");
}
@Override
public void showView() {}
@Override
public void hideView() {}
}
//Presenter
class MyPresenter implements LifecycleObserver {
private static final String TAG = "Lifecycle_Test";
private final IView mView;
public MyPresenter(IView view) {mView = view;}
@OnLifecycleEvent(value = Lifecycle.Event.ON_START)
private void getDataOnStart(LifecycleOwner owner){
Log.i(TAG, "getDataOnStart: ");
Util.checkUserStatus(result -> {
//checkUserStatus是耗時操作,回調後檢查當前生命週期狀態
if (owner.getLifecycle().getCurrentState().isAtLeast(STARTED)) {
start();
mView.showView();
}
});
}
@OnLifecycleEvent(value = Lifecycle.Event.ON_STOP)
private void hideDataOnStop(){
Log.i(TAG, "hideDataOnStop: ");
stop();
mView.hideView();
}
}
//IView
interface IView {
void showView();
void hideView();
}
這裏是讓Presenter實現LifecycleObserver接口,同樣在方法上註解要觸發的生命週期,最後在Activity中作爲觀察者添加到Lifecycle中。
這樣做好處是啥呢? 當Activity生命週期發生變化時,MyPresenter就可以感知並執行方法,不需要在MainActivity的多個生命週期方法中調用MyPresenter的方法了。
- 所有方法調用操作都由組件本身管理:Presenter類自動感知生命週期,如果需要在其他的Activity/Fragment也使用這個Presenter,只需添加其爲觀察者即可。
- 讓各個組件存儲自己的邏輯,減輕Activity/Fragment中代碼,更易於管理;
—— 上面提到的第一個問題點就解決了。
另外,注意到 getDataOnStart()中耗時校驗回調後,對當前生命週期狀態進行了檢查:至少處於STARTED狀態纔會繼續執行start()方法,也就是保證了Activity停止後不會走start()方法;
—— 上面提到的第二個問題點也解決了。
2.2.3 自定義LifecycleOwner
在Activity中調用getLifecycle()能獲取到Lifecycle實例,那getLifecycle()是哪裏定義的方法呢
?是接口LifecycleOwner,顧明來思義,生命週期擁有者:
/**
* 生命週期擁有者
* 生命週期事件可被 自定義的組件 用來 處理生命週期事件的變化,同時不會在Activity/Fragmen中寫任何代碼
*/
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
Support Library 26.1.0及以上、AndroidX的 Fragment 和 Activity 已實現 LifecycleOwner 接口,所以我們在Activity中可以直接使用getLifecycle()。
如果有一個自定義類並希望使其成爲LifecycleOwner,可以使用LifecycleRegistry類,它是Lifecycle的實現類,但需要將事件轉發到該類:
public class MyActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry lifecycleRegistry;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleRegistry = new LifecycleRegistry(this);
lifecycleRegistry.markState(Lifecycle.State.CREATED);
}
@Override
public void onStart() {
super.onStart();
lifecycleRegistry.markState(Lifecycle.State.STARTED);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return lifecycleRegistry;
}
}
MyActivity實現LifecycleOwner,getLifecycle()返回lifecycleRegistry實例。lifecycleRegistry實例則是在onCreate創建,並且在各個生命週期內調用markState()方法完成生命週期事件的傳遞。這就完成了LifecycleOwner的自定義,也即MyActivity變成了LifecycleOwner,然後就可以和 實現了LifecycleObserver的組件配合使用了。
補充一點,觀察者的方法可以接受一個參數LifecycleOwner,就可以用來獲取當前狀態、或者繼續添加觀察者。 若註解的是ON_ANY還可以接收Event,用於區分是哪個事件。如下:
class TestObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
void onCreated(LifecycleOwner owner) {
// owner.getLifecycle().addObserver(anotherObserver);
// owner.getLifecycle().getCurrentState();
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
void onAny(LifecycleOwner owner, Lifecycle.Event event) {
// event.name()
}
}
2.3 Application生命週期 ProcessLifecycleOwner
之前對App進入前後臺的判斷是通過registerActivityLifecycleCallbacks(callback)方法,然後在callback中利用一個全局變量做計數,在onActivityStarted()中計數加1,在onActivityStopped方法中計數減1,從而判斷前後臺切換。
而使用ProcessLifecycleOwner可以直接獲取應用前後臺切換狀態。(記得先引入lifecycle-process依賴)
使用方式和Activity中類似,只不過要使用ProcessLifecycleOwner.get()獲取ProcessLifecycleOwner,代碼如下:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//註冊App生命週期觀察者
ProcessLifecycleOwner.get().getLifecycle().addObserver(new ApplicationLifecycleObserver());
}
/**
* Application生命週期觀察,提供整個應用進程的生命週期
*
* Lifecycle.Event.ON_CREATE只會分發一次,Lifecycle.Event.ON_DESTROY不會被分發。
*
* 第一個Activity進入時,ProcessLifecycleOwner將分派Lifecycle.Event.ON_START, Lifecycle.Event.ON_RESUME。
* 而Lifecycle.Event.ON_PAUSE, Lifecycle.Event.ON_STOP,將在最後一個Activit退出後後延遲分發。如果由於配置更改而銷燬並重新創建活動,則此延遲足以保證ProcessLifecycleOwner不會發送任何事件。
*
* 作用:監聽應用程序進入前臺或後臺
*/
private static class ApplicationLifecycleObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
private void onAppForeground() {
Log.w(TAG, "ApplicationObserver: app moved to foreground");
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private void onAppBackground() {
Log.w(TAG, "ApplicationObserver: app moved to background");
}
}
}
看到確實很簡單,和前面Activity的Lifecycle用法幾乎一樣,而我們使用ProcessLifecycleOwner就顯得很優雅了。 生命週期分發邏輯已在註釋裏說明。
三、 源碼分析
Lifecycle的使用很簡單,接下來就是對Lifecycle原理和源碼的解析了。
我們可以先猜下原理:LifecycleOwner(如Activity)在生命週期狀態改變時(也就是生命週期方法執行時),遍歷觀察者,獲取每個觀察者的方法上的註解,如果註解是@OnLifecycleEvent且value是和生命週期狀態一致,那麼就執行這個方法。 這個猜測合理吧?下面你來看看。
3.1 Lifecycle類
先來瞅瞅Lifecycle:
public abstract class Lifecycle {
//添加觀察者
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
//移除觀察者
@MainThread
public abstract void removeObserver(@NonNull LifecycleObserver observer);
//獲取當前狀態
public abstract State getCurrentState();
//生命週期事件,對應Activity生命週期方法
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY //可以響應任意一個事件
}
//生命週期狀態. (Event是進入這種狀態的事件)
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
//判斷至少是某一狀態
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
Lifecycle 使用兩種主要枚舉跟蹤其關聯組件的生命週期狀態:
- Event,生命週期事件,這些事件對應Activity/Fragment生命週期方法。
- State,生命週期狀態,而Event是指進入一種狀態的事件。
Event觸發的時機:
- ON_CREATE、ON_START、ON_RESUME事件,是在LifecycleOwner對應的方法執行 之後 分發。
- ON_PAUSE、ON_STOP、ON_DESTROY事件,是在LifecycleOwner對應的方法調用 之前 分發。
這保證了LifecycleOwner是在這個狀態內。
官網有個圖很清晰:
3.2 Activity對LifecycleOwner的實現
前面提到Activity實現了LifecycleOwner,所以才能直接使用getLifecycle(),具體是在androidx.activity.ComponentActivity中:
//androidx.activity.ComponentActivity,這裏忽略了一些其他代碼,我們只看Lifecycle相關
public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner{
...
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
...
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
ReportFragment.injectIfNeededIn(this); //使用ReportFragment分發生命週期事件
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
@CallSuper
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
Lifecycle lifecycle = getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED);
}
super.onSaveInstanceState(outState);
mSavedStateRegistryController.performSave(outState);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
這裏忽略了一些其他代碼,我們只看Lifecycle相關。
看到ComponentActivity實現了接口LifecycleOwner,並在getLifecycle()返回了LifecycleRegistry實例。前面提到LifecycleRegistry是Lifecycle具體實現。
然後在onSaveInstanceState()中設置mLifecycleRegistry的狀態爲State.CREATED,然後怎麼沒有了?其他生命週期方法內咋沒處理?what?和猜測的不一樣啊。 別急,在onCreate()中有這麼一行:ReportFragment.injectIfNeededIn(this);
,這個就是關鍵所在。
3.3 生命週期事件分發——ReportFragment
//專門用於分發生命週期事件的Fragment
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
//在API 29及以上,可以直接註冊回調 獲取生命週期
activity.registerActivityLifecycleCallbacks(
new LifecycleCallbacks());
}
//API29以前,使用fragment 獲取生命週期
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
@SuppressWarnings("deprecation")
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);//使用LifecycleRegistry的handleLifecycleEvent方法處理事件
}
}
}
@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);
}
...省略onStop、onDestroy
private void dispatch(@NonNull Lifecycle.Event event) {
if (Build.VERSION.SDK_INT < 29) {
dispatch(getActivity(), event);
}
}
//在API 29及以上,使用的生命週期回調
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);
}
...省略onStop、onDestroy
}
}
首先injectIfNeededIn()內進行了版本區分:在API 29及以上 直接使用activity的registerActivityLifecycleCallbacks 直接註冊了生命週期回調,然後給當前activity添加了ReportFragment,注意這個fragment是沒有佈局的。
然後, 無論LifecycleCallbacks、還是fragment的生命週期方法 最後都走到了 dispatch(Activity activity, Lifecycle.Event event)方法,其內部使用LifecycleRegistry的handleLifecycleEvent方法處理事件。
而ReportFragment的作用就是獲取生命週期而已,因爲fragment生命週期是依附Activity的。好處就是把這部分邏輯抽離出來,實現activity的無侵入。如果你對圖片加載庫Glide比較熟,就會知道它也是使用透明Fragment獲取生命週期的。
3.4 生命週期事件處理——LifecycleRegistry
到這裏,生命中週期事件的處理有轉移到了 LifecycleRegistry 中:
//LifecycleRegistry.java
//系統自定義的保存Observer的map,可在遍歷中增刪
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);//獲取event發生之後的將要處於的狀態
moveToState(next);//移動到這個狀態
}
private void moveToState(State next) {
if (mState == next) {
return;//如果和當前狀態一致,不處理
}
mState = next; //賦值新狀態
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
return;
}
mHandlingEvent = true;
sync(); //把生命週期狀態同步給所有觀察者
mHandlingEvent = false;
}
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
while (!isSynced()) { //isSynced()意思是 所有觀察者都同步完了
mNewEventOccurred = false;
//mObserverMap就是 在activity中添加observer後 用於存放observer的map
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
...
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);
}
邏輯很清晰:使用getStateAfter()獲取event發生之後的將要處於的狀態(看前面那張圖很好理解),moveToState()是移動到新狀態,最後使用sync()把生命週期狀態同步給所有觀察者。
注意到sync()中有個while循環,很顯然是在遍歷觀察者。並且很顯然觀察者是存放在mObserverMap中的,而mObserverMap對觀察者的添加 很顯然 就是 Activity中使用getLifecycle().addObserver()這裏:
//LifecycleRegistry.java
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//帶狀態的觀察者,這個狀態的作用:新的事件觸發後 遍歷通知所有觀察者時,判斷是否已經通知這個觀察者了
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
//observer作爲key,ObserverWithState作爲value,存到mObserverMap
if (previous != null) {
return;//已經添加過,不處理
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
return;//lifecycleOwner退出了,不處理
}
//下面代碼的邏輯:通過while循環,把新的觀察者的狀態 連續地 同步到最新狀態mState。
//意思就是:雖然可能添加的晚,但把之前的事件一個個分發給你(upEvent方法),即粘性
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);//計算目標狀態
mAddingObserverCounter++;
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);
}
if (!isReentrance) {
sync();
}
mAddingObserverCounter--;
}
用observer創建帶狀態的觀察者ObserverWithState,observer作爲key、ObserverWithState作爲value,存到mObserverMap。 接着做了安全判斷,最後把新的觀察者的狀態 連續地 同步到最新狀態mState,意思就是:雖然可能添加的晚,但會把之前的事件一個個分發給你,即粘性。
回到剛剛sync()的while循環,看看如何處理分發事件:
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;
// no need to check eldest for nullability, because isSynced does it for us.
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
private boolean isSynced() {
if (mObserverMap.size() == 0) {
return true;
}//最老的和最新的觀察者的狀態一致,都是ower的當前狀態,說明已經同步完了
State eldestObserverState = mObserverMap.eldest().getValue().mState;
State newestObserverState = mObserverMap.newest().getValue().mState;
return eldestObserverState == newestObserverState && mState == newestObserverState;
}
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator = mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {//正向遍歷,從老到新
Entry<LifecycleObserver, ObserverWithState> 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));//observer獲取事件
popParentState();
}
}
}
private void backwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator = mObserverMap.descendingIterator();
while (descendingIterator.hasNext() && !mNewEventOccurred) {//反向遍歷,從新到老
Entry<LifecycleObserver, ObserverWithState> 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);//observer獲取事件
popParentState();
}
}
}
循環條件是!isSynced(),若最老的和最新的觀察者的狀態一致,且都是ower的當前狀態,說明已經同步完了。
沒有同步完就進入循環體:
- mState比最老觀察者狀態小,走backwardPass(lifecycleOwner):從新到老分發,循環使用downEvent()和observer.dispatchEvent(),連續分發事件;
- mState比最新觀察者狀態大,走forwardPass(lifecycleOwner):從老到新分發,循環使用upEvent()和observer.dispatchEvent(),連續分發事件。
接着ObserverWithState類型的observer就獲取到了事件,即observer.dispatchEvent(lifecycleOwner, event),下面來看看它是如何讓加了對應註解的方法執行的。
3.5 事件回調後 方法執行
我們繼續看下 ObserverWithState:
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;
}
}
mState的作用是:新的事件觸發後 遍歷通知所有觀察者時,判斷是否已經通知這個觀察者了,即防止重複通知。
mLifecycleObserver是使用Lifecycling.getCallback(observer)獲取的GenericLifecycleObserver實例。GenericLifecycleObserver是接口,繼承自LifecycleObserver:
//接受生命週期改變並分發給真正的觀察者
public interface LifecycleEventObserver extends LifecycleObserver {
//生命週期狀態變化
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
也就說,LifecycleEventObserver 給 LifecycleObserver 增加了感知生命週期狀態變化的能力。
看看Lifecycling.getCallback(observer):
@NonNull
static LifecycleEventObserver lifecycleEventObserver(Object object) {
...省略很多類型判斷的代碼
return new ReflectiveGenericLifecycleObserver(object);
}
方法內有很多對observer進行類型判斷的代碼,我們這裏關注的是ComponentActivity,所以LifecycleEventObserver的實現類就是ReflectiveGenericLifecycleObserver了:
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
private final Object mWrapped;
private final CallbackInfo mInfo;
ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());//存放了event與加了註解方法的信息
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) {
mInfo.invokeCallbacks(source, event, mWrapped);//執行對應event的觀察者的方法
}
}
它的onStateChanged()方法內部使用CallbackInfo的invokeCallbacks方法,這裏應該就是執行觀察者的方法了。
ClassesInfoCache內部用Map存了 所有觀察者的回調信息,CallbackInfo是當前觀察者的回調信息。
先看下CallbackInfo實例的創建,ClassesInfoCache.sInstance.getInfo(mWrapped.getClass()):
//ClassesInfoCache.java
private final Map<Class, CallbackInfo> mCallbackMap = new HashMap<>();//所有觀察者的回調信息
private final Map<Class, Boolean> mHasLifecycleMethods = new HashMap<>();//觀察者是否有註解了生命週期的方法
CallbackInfo getInfo(Class<?> klass) {
CallbackInfo existing = mCallbackMap.get(klass);//如果已經存在當前觀察者回調信息 直接取
if (existing != null) {
return existing;
}
existing = createInfo(klass, null);//沒有就去收集信息並創建
return existing;
}
private CallbackInfo createInfo(Class<?> klass, @Nullable Method[] declaredMethods) {
Class<?> superclass = klass.getSuperclass();
Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>();//生命週期事件到來 對應的方法
...
Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);//反射獲取觀察者的方法
boolean hasLifecycleMethods = false;
for (Method method : methods) {//遍歷方法 找到註解OnLifecycleEvent
OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
if (annotation == null) {
continue; //沒有註解OnLifecycleEvent 就return
}
hasLifecycleMethods = true;//有註解OnLifecycleEvent
Class<?>[] params = method.getParameterTypes(); //獲取方法參數
int callType = CALL_TYPE_NO_ARG;
if (params.length > 0) { //有參數
callType = CALL_TYPE_PROVIDER;
if (!params[0].isAssignableFrom(LifecycleOwner.class)) {
throw new IllegalArgumentException(//第一個參數必須是LifecycleOwner
"invalid parameter type. Must be one and instanceof LifecycleOwner");
}
}
Lifecycle.Event event = annotation.value();
if (params.length > 1) {
callType = CALL_TYPE_PROVIDER_WITH_EVENT;
if (!params[1].isAssignableFrom(Lifecycle.Event.class)) {
throw new IllegalArgumentException(//第二個參數必須是Event
"invalid parameter type. second arg must be an event");
}
if (event != Lifecycle.Event.ON_ANY) {
throw new IllegalArgumentException(//有兩個參數 註解值只能是ON_ANY
"Second arg is supported only for ON_ANY value");
}
}
if (params.length > 2) { //參數不能超過兩個
throw new IllegalArgumentException("cannot have more than 2 params");
}
MethodReference methodReference = new MethodReference(callType, method);
verifyAndPutHandler(handlerToEvent, methodReference, event, klass);//校驗方法並加入到map handlerToEvent 中
}
CallbackInfo info = new CallbackInfo(handlerToEvent);//獲取的 所有註解生命週期的方法handlerToEvent,構造回調信息實例
mCallbackMap.put(klass, info);//把當前觀察者的回調信息存到ClassesInfoCache中
mHasLifecycleMethods.put(klass, hasLifecycleMethods);//記錄 觀察者是否有註解了生命週期的方法
return info;
}
- 如果不存在當前觀察者回調信息,就使用createInfo()方法收集創建
- 先反射獲取觀察者的方法,遍歷方法 找到註解了OnLifecycleEvent的方法,先對方法的參數進行了校驗。
- 第一個參數必須是LifecycleOwner;第二個參數必須是Event;有兩個參數 註解值只能是ON_ANY;參數不能超過兩個
- 校驗方法並加入到map,key是方法,value是Event。map handlerToEvent是所有的註解了生命週期的方法。
- 遍歷完,然後用 handlerToEvent來構造 當前觀察者回調信息CallbackInfo,存到ClassesInfoCache的mCallbackMap中,並記錄 觀察者是否有註解了生命週期的方法。
整體思路還是很清晰的,繼續看CallbackInfo的invokeCallbacks方法:
static class CallbackInfo {
final Map<Lifecycle.Event, List<MethodReference>> mEventToHandlers;//Event對應的多個方法
final Map<MethodReference, Lifecycle.Event> mHandlerToEvent;//要回調的方法
CallbackInfo(Map<MethodReference, Lifecycle.Event> handlerToEvent) {
mHandlerToEvent = handlerToEvent;
mEventToHandlers = new HashMap<>();
//這裏遍歷mHandlerToEvent來獲取mEventToHandlers
for (Map.Entry<MethodReference, Lifecycle.Event> entry : handlerToEvent.entrySet()) {
Lifecycle.Event event = entry.getValue();
List<MethodReference> methodReferences = mEventToHandlers.get(event);
if (methodReferences == null) {
methodReferences = new ArrayList<>();
mEventToHandlers.put(event, methodReferences);
}
methodReferences.add(entry.getKey());
}
}
@SuppressWarnings("ConstantConditions")
void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);//執行對應event的方法
invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,target);//執行註解了ON_ANY的方法
}
private static void invokeMethodsForEvent(List<MethodReference> handlers,
LifecycleOwner source, Lifecycle.Event event, Object mWrapped) {
if (handlers != null) {
for (int i = handlers.size() - 1; i >= 0; i--) {//執行Event對應的多個方法
handlers.get(i).invokeCallback(source, event, mWrapped);
}
}
}
}
很好理解,執行對應event的方法、執行註解了ON_ANY的方法。其中mEventToHandlers是在創建CallbackInfo時由遍歷mHandlerToEvent來獲取,存放了每個Event對應的多個方法。
最後看看handlers.get(i).invokeCallback,即MethodReference中:
static class MethodReference {
...
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);//一個參數的:LifecycleOwner
break;
case CALL_TYPE_PROVIDER_WITH_EVENT:
mMethod.invoke(target, source, event);//兩個參數的:LifecycleOwner,Event
break;
}
}
...
}
...
}
根據不同參數類型,執行對應方法。
到這裏,整個流程就完整了。實際看了這麼一大圈,基本思路和我們的猜想是一致的。
這裏借Android Jetpack架構組件(三)一文帶你瞭解Lifecycle(原理篇)的圖總結下:
四、總結
本文先介紹了Jetpack和AAC的概念,這是Android官方推薦的通用開發工具集。其中AAC是架構組件,是本系列文章的介紹內容。接着介紹了AAC的基礎組件Lifecycle,它能讓開發者更好的管理Activity/Fragment生命週期。最後詳細分析了Lifecycle源碼及原理。
Jetpack的AAC是我們後續開發Android必備知識,也是完成MVVM架構的基礎。Lifecycle更是AAC中的基礎,所以完整掌握本篇內容十分必要。
.
感謝與參考:
Android Jetpack架構組件(三)一文帶你瞭解Lifecycle(原理篇)
Android架構組件(2)LifecycleRegistry 源碼分析
.
你的 點贊、評論,是對我的巨大鼓勵!