Android生命週期元件Lifecycle使用詳解

warmcheng發表於2019-02-27

前言

2018 年的 Google I/O 大會上,Google 釋出了 Android Jetpack,並稱其為下一代的 Android 元件,旨在幫助開發者加快應用開發速度。準確來講,Jetpack 是一系列 Android 軟體元件的集合,它包括基礎元件、架構元件、行為元件、介面元件。其中的 Android Architecture Components 指的就是這裡的 “架構元件”。

Android Architecture Components 是 Google 推薦的一個構建 APP 的應用架構,它包含了一些列架構相關元件。而本篇文章我們要介紹的 Lifecycle 就是其中的一個與生命週期相關的庫,同時,Lifecycle 也跟 LiveData 和 ViewModel 兩個庫緊密聯絡,想要搞懂後兩者,就必須先搞懂它。

具體各元件之間的關係,以及各自在 Jetpack 中的地位,可以參見下面兩幅來源於官網的圖片。

Lifecycle 的作用

Lifecycle 是具有生命週期感知能力的元件,也就是說,我們能在 Activity 或者 Fragment 的生命週期發生變化的時候得到通知。我們往往會在 Activity 的各種生命中週期方法裡執行特定的方法,比如,進行廣播的註冊和解綁、Eventbus 的註冊和解綁等:

public class TestActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
    }

    @Override
    protected void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }
}
複製程式碼

如果我們把很多這種需要跟生命週期相關的邏輯程式碼都直接放在 Activity 的生命週期方法中,Activity 將會變得難以維護。通過 Lifecycle,我們就能避免這種問題。因為本質上我們需要的只是 Activity 或者 Fragment 的生命週期發生改變的時候能通知到我們,以便我們在對應生命週期中執行對應的方法。

Lifecycle 的基本使用

2.0、 匯入 Lifecycle 依賴

Lifecycle 被包含在 support library 26.1.0 及之後的依賴包中,如果我們的專案依賴的支援庫版本在 26.1.0及以上,那麼不需要額外匯入 Lifecycle 庫,本篇例子中使用的支援庫是 28.0.0 :

    implementation 'com.android.support:appcompat-v7:28.0.0'複製程式碼

如果支援庫版本小於 26.1.0 ,就需要單獨匯入 Lifecycle 庫 :

    implementation "android.arch.lifecycle:runtime:1.1.1"複製程式碼

當然,如果專案已經遷移到了 AndroidX,可以使用下面的方式引入 :

    implementation "androidx.lifecycle:lifecycle-runtime:2.0.0"複製程式碼

還是建議大家嘗試儘快把專案遷移為AndroidX,因為很多更新,會最先在 AndroidX 中釋出,逐漸擺脫傳統的support包。比如這裡要講的 Lifecycle 在 AndroidX 中已經升級到了 2.x 版本,而支援庫中還是 1.x 版本。

鑑於支援庫一般都在 26.1.0 以上,並且尚有大部分使用者未遷移到AndroidX,在本篇文章中,我們使用 support library 28.0.0 中預設包含的 Lifecycle 庫。我們在專案的 app 目錄下的 build.gradle 檔案中新增以下依賴:

    implementation 'com.android.support:appcompat-v7:28.0.0'複製程式碼

以 support library 版本在 26.1.0 及以上為前提,這裡我們分兩種情況來講。一種是我們建立的Activity 繼承自 AppCompatActivity(以Activity 為例,Fragment類似),另一種是建立的 Activity 繼承自普通的 Activity,而非 AppCompatActivity。

這裡要先說一點, Lifecycle 的實現機制是觀察者模式,整體上知道了這個,再講它的使用過程就比較容易理解了:
1. 構建一個 Lifecycle 物件(通過一個實現了 LifecycleOwner 介面的物件的 getLifecycle()方法返回),這個物件就是一個被觀察者,具有生命週期感知能力
2. 構建一個 LifecycleObserver 物件,它對指定的 Lifecycle 物件進行監聽
3. 通過將 Lifecycle 物件的 addObserver(…) 方法,將 Lifecycle 物件和 LifecycleObserver 物件進行繫結

2.1、 繼承自 AppCompatActivity

首先,我們建立一個 MyObserver.java 類,讓它實現 LifecycleObserver 介面( LifecycleObserver 介面是一個空介面,主要是給註解處理器使用),如下:

public class MyObserver implements LifecycleObserver {

    private static final String TAG = "MyObserver";

    // 使用註解  @OnLifecycleEvent 來表明該方法需要監聽指定的生命週期事件
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void connectListener() {
//        ...
        Log.d(TAG, "connectListener:  --------   onResume" );
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void disconnectListener() {
//        ...
        Log.d(TAG, "disconnectListener: -------   onPause");
    }
}
複製程式碼

可以看到,我們通過在方法上使用@OnLifecycleEvent 註解使得該方法具有了生命週期感知能力。括號裡面的引數,表明需要監聽的是什麼生命週期事件。Lifecycle 主要就是通過 EventState 這兩個列舉類來跟蹤所關聯元件的生命週期狀態。具體的 Event 和 State 之間的轉換關係,可以參照下圖:

接下來,讓我們的 Activity 繼承自 AppCompatActivity,然後在 onCreate(…) 方法中通過getLifecycle().addObserver(new MyObserver())完成 Lifecycle 和LifecycleObserver 的繫結。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 就只需要這一行程式碼,簡潔吧
        getLifecycle().addObserver(new MyObserver());
    }
}複製程式碼

然後我們就可以執行下程式,切換到 Home 也或者按返回鍵,就能看到隨著生命週期的變化,MyObserver() 中定義的方法在控制檯中也被正確地列印了出來。

是不是覺得特別簡單。

但之所以毫不費力,是因為有人替你“負重前行”。在 support library 26.1.0 及以後的支援庫中,AppCompatActivity 的祖先類 SupportActivity已經預設實現了 LifecycleOwner 介面,通過其 getLifecycle() 方法可以直接返回一個 Lifecycle 物件。之後我們就可以通過該物件的 addObserver(…) 方法將 Lifecycle 跟指定的 LifecycleObserver 進行繫結。

2.2、 繼承自普通的 Activity

首先,我們仍然需要像上面的方式,來建立一個MyObserver 物件。

這次我們建立一個繼承自普通的 Activity 的 Activity ,那自然無法直接使用 getLifecycle() 方法來獲取 Lifecycle 。無法直接使用,那我們能否模仿 AppCompatActivity的實現,來自己建立 Lifecycle 物件呢?當然可以。這時候,我們就需要自己實現LifecycleOwner介面,並在具體的生命週期下通過 LifecycleRegistrymarkState(...)方法來主動進行事件的分發。請看下面改造過的 MainActivity.java 程式碼 :

public class MainActivity extends Activity implements LifecycleOwner {

    private LifecycleRegistry mLifecycleRegistry;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mLifecycleRegistry = new LifecycleRegistry(this);
        getLifecycle().addObserver(new MyObserver());
        mLifecycleRegistry.markState(Lifecycle.State.CREATED);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mLifecycleRegistry.markState(Lifecycle.State.RESUMED);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mLifecycleRegistry.markState(Lifecycle.State.STARTED);
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
}
複製程式碼

MainActivity實現了LifecycleOwner介面(實現該介面的物件,即是 Lifecycle 的持有者),並在其 getLifecycle( ) 方法中返回了一個 LifecycleRegistry物件,而 LifecycleRegistry 是 Lifecycle 的子類。其他使用方式,則完全相同。

為了讓使用更加方便靈活,Lifecycle 還提供了查詢當前元件所處的生命週期狀態的方法:

lifecycle.getCurrentState().isAtLeast(STARTED)複製程式碼

總結

  1. 實現了 LifecycleObserver 介面的類可以和實現了 LifecycleOwner 介面的類無縫工作,因為 LifecycleOwner 可以提供一個 Lifecycle 物件,而 LifecycleObserver 就正需要對這個 Lifecycle 物件進行監聽呢。
  2. LifecycleOwner 是從特定的類(比如 Activity 或者 Fragment 等)中抽象出來的Lifecycle 的持有者。
  3. LifecycleRegistry 類用於註冊和反註冊需要觀察當前元件生命週期的 LifecycleObserver

注意

從 1.0.0-rc1 版本的 Lifecycle 包開始,當 Activity 的 onSaveInstanceState() 方法呼叫結束之後,Lifecycle 將立刻被標記為 CREATED 和 ON_STOP ,而不是等 onStop() 方法呼叫結束。這點和 API level 26 或者更低版本上 Activity 的生命週期的呼叫順序並不匹配,需要稍加註意。有具體需求的可以進一步查閱相關文件。

下篇文章,將會對 Lifecycle 的原始碼進行剖析。

更多最新訊息,歡迎關注我的公眾號獲取:


相關文章