1. 程式人生 > >Android官方架構組件介紹之LifeCycle(一)

Android官方架構組件介紹之LifeCycle(一)

mave 工程 視圖 平時 清理 star new 內部 serve

Android官方架構組件介紹之LifeCycle

下面是官方提供的Android App開發的架構圖:

技術分享圖片

從上圖可以看到一些關鍵字:ViewModel,LiveData,Room等。其實看了上面視頻的會發現Google官方Android架構組件一共包括以下幾個:

  • LifeCycle : 與Activity和Fragment的生命周期有關
  • LiveData :異步可訂閱數據,也是生命周期感知
  • ViewModel :視圖數據持有模型,也是生命周期感知
  • Room :SQLite抽象層,用於簡化SQLite數據存儲

這篇文章主要講解LifeCycle在項目的簡單用法

AS中添加依賴

首先在工程根目錄的build.gradle

中添加一下內容:

allprojects {
    repositories {
        jcenter()
        maven { url ‘https://maven.google.com‘ }  //添加此行
    }
}

然後在應用目錄下的build.gradle中添加以下依賴:

//For Lifecycles, LiveData, and ViewModel
compile "android.arch.lifecycle:runtime:1.0.0-alpha1"
compile "android.arch.lifecycle:extensions:1.0.0-alpha1"
annotationProcessor 
"android.arch.lifecycle:compiler:1.0.0-alpha1" //For Room compile "android.arch.persistence.room:runtime:1.0.0-alpha1" annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"

LifeCycle相關使用

在我們平時的項目中經常會遇到很多需要依賴生命周期的邏輯處理,比如有這麽一個需求。
在某個Activity我們需要在屏幕上展現用戶的地理位置。簡單的實現方法如下:

lass MyLocationListener {
    
public MyLocationListener(Context context, Callback callback) { // ... } void start() { // connect to system location service } void stop() { // disconnect from system location service } } class MyActivity extends AppCompatActivity { private MyLocationListener myLocationListener; public void onCreate(...) { myLocationListener = new MyLocationListener(this, (location) -> { // update UI }); } public void onStart() { super.onStart(); myLocationListener.start(); } public void onStop() { super.onStop(); myLocationListener.stop(); } }

雖然以上代碼看起來很簡潔,但在實際項目中的onStart,onStop方法可能會變得相當龐大。
此外,實際情況可能並不像上面這麽簡單,例如我們需要在start位置監聽前做用戶狀態檢測,檢測是一個耗時的任務,那麽很有可能在檢測結束前用戶提前退出了Activity,這時候就會導致myLocationListener.start()myLocationListener.stop()後面調用,從而引起很多難以定位的問題。代碼如下:

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, location -> {
            // update UI
        });
    }

    public void onStart() {
        super.onStart();
        Util.checkUserStatus(result -> {
            // what if this callback is invoked AFTER activity is stopped?
            if (result) {
                myLocationListener.start();
            }
        });
    }

    public void onStop() {
        super.onStop();
        myLocationListener.stop();
    }
}

這時候就該今天的主角LifeCycle出場了。它提供了一套接口幫助你處理這些問題。

LifeCycle

LifeCyle類持有Activity或者Fragment的生命周期相關信息,並且支持其他對象監聽這些狀態。

LifeCyle有兩個枚舉用於追蹤生命周期中的狀態。

Event

這是生命周期的事件類,會在Framework和LifeCycle間傳遞,這些事件映射到Activity和Fragment的回調事件中。

State

LifeCycle所持有Activity或Fragment的當前狀態。

一個類想要監聽LifeCycle的狀態,只需要給其方法加上註解:

public class MyObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause() {
    }
}
aLifecycleOwner.getLifecycle().addObserver(new MyObserver());

LifeCycleOwner

LifeCycleOwner是一個只有一個方法的接口用於表明其有一個LifeCycle對象。這個方法為getLifecycle()
這個對象給Acitivity,Fragment和LifeCycle提供了一個很好的抽象關系,Activity和Fragment只要實現這個接口就能配合LifeCycle實現生命周期監聽。

註意:由於目前LifeCycle處於alpha階段,所以Fragment和AppCompatActivity並不會實現這些方法,在此之前,可以使用LifecycleActivityLifecycleFragment。等LifeCycle趨於穩定後,Fragment和AppCompatActivity會默認實現這些。

對於之前的位置監聽的例子,我們可以讓MyLocationListener繼承LifecycleObserver,在onCreate中使用LifeCycle進行初始化,剩下的問題則不必擔心了。因為MyLocationListener有能力進行生命周期的判斷。

class MyActivity extends LifecycleActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        //此處進行初始化getLifecycle()傳入LifeCycle對象
        myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {
            // update UI
        });
        //檢測用戶狀態並啟用監聽
        Util.checkUserStatus(result -> {
            if (result) {
                myLocationListener.enable();
            }
        });
  }
}

下面看一下MyLocationListener

class MyLocationListener implements LifecycleObserver {
    private boolean enabled = false;
    public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
       ...
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void start() {
        if (enabled) {
           // connect
        }
    }

    public void enable() {
        enabled = true;
        //?
        if (lifecycle.getState().isAtLeast(STARTED)) {
            // connect if not connected
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void stop() {
        // disconnect if connected
    }
}

LifeCycle最重要的特性就是在?處,他可以提供主動查詢生命周期狀態的方法。這樣就避免了上面遇到的myLocationListener.start()myLocationListener.stop()後面調用的問題。

通過以上的實現,我們的LocationListener是完全的生命周期感知了,它可以進行自己的初始化和資源清理而不必受Activity或者Fragment的管理。這時候如果我們在其他Activity或者Fragment中使用LocationListener,我們只需要初始化它就行了,不必再擔心生命周期對它的影響,因為它內部會做好這一切。

通過LefeCycle工作的類我們稱之為生命周期感知。鼓勵需要使用Android生命周期的類的庫提供生命周期感知組件,以便客戶端可以輕松地在客戶端上集成這些類,而無需手動生命周期管理。

LiveData就是生命周期感知組件的示例,將LiveData和ViewModel一起使用,可以在遵循Android生命周期的情況下,更容易的使用數據來填充UI。

生命周期的最佳實踐

  • 保持你的UI(Activity和Fragment)盡可能簡潔。它們不應該試圖獲取它們的數據而是使用ViewModel來執行此操作,並通過LiveData的回調將數據更新到UI中。
  • 嘗試編寫數據驅動的UI,你的UI的責任是在數據更改時更新視圖,或將用戶操作通知給ViewModel。
  • 將你的數據邏輯放在ViewModel類中。 ViewModel應該作為UI和其他數據操作的連接器。值得註意的是,ViewModel並不負責提取數據(例如,從網絡)。相反,ViewModel應該調用其他接口來執行此工作,然後將結果提供給UI。
  • 使用Data Binding可以讓你的的UI代碼變得相當幹凈利落。這將使你的UI更具聲明性,並最大限度地減少書寫UI更新的代碼。如果您更喜歡在Java中執行此操作,請使用像Butter Knife這樣的庫來避免使用樣板代碼並進行更好的抽象。
  • 如果你有一個復雜的UI,請考慮創建一個Presenter類來處理UI修改。這通常是過度架構的,但可能有助於使你的UI更容易測試。
  • 不要在ViewModel中引用View或Activity上下文。如果ViewModel在Activity或View銷毀的情況下依舊存活,這時將導致內存泄漏。

補充

在自定義的Activity或Fragment中實現LifeCycleOwner,可以實現LifecycleRegistryOwner這個接口。而不是繼承(LifeCycleFragment和LifeCycleActivity)

public class MyFragment extends Fragment implements LifecycleRegistryOwner {
    LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public LifecycleRegistry getLifecycle() {
        return lifecycleRegistry;
    }
}

如果你要在自定義的類中實現LifeCycleOwner,可以使用LifecycleRegistry,但是你需要主動向其轉發生命周期的事件。但如果你自定義類是Fragment和Activity的話並且它們實現的是LifecycleRegistryOwner,那麽事件轉發都是自動完成的。

Android官方架構組件介紹之LifeCycle(一)