“終於懂了“系列:Jetpack AAC完整解析(一)Lifecycle 完全掌握! 一、Android Jetpack 介紹 二、Lifecycle 三、 源碼分析 四、總結

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 使用兩種主要枚舉跟蹤其關聯組件的生命週期狀態:

  1. Event,生命週期事件,這些事件對應Activity/Fragment生命週期方法。
  2. 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中的基礎,所以完整掌握本篇內容十分必要。

.

感謝與參考:

Lifecycle官方文檔

Android Jetpack架構組件(三)一文帶你瞭解Lifecycle(原理篇)

Android架構組件(2)LifecycleRegistry 源碼分析

.

你的 點贊、評論,是對我的巨大鼓勵!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章