天天看點

Android Architecture Components應用架構元件實戰

    Google IO 2017釋出Android Architecture Components,這個新的架構庫旨在幫助我們設計健壯、可測試的和可維護的應用程式。AAC主要提供了Lifecycle,LiveData,ViewModel ,Room等功能,在代碼中使用它會使得App架構更加健壯,避免記憶體洩漏和一些空指針等問題。整體的架構如下:

Android Architecture Components應用架構元件實戰

        在使用這些元件前先需要在gradle中進行加入如下依賴:

implementation 'android.arch.lifecycle:extensions:1.1.0'
annotationProcessor "android.arch.lifecycle:compiler:1.1.0"
implementation 'android.arch.persistence.room:runtime:1.0.0'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'      

一、Lifecycle

         Lifecycle是一個生命周期管理類,用來對外界提供的一個接口,用來監控Activity或者Fragment的生命周期,使得生命周期從Activity或者Fragment中解耦出來。

        1、讓需要管理生命周期的類實作LifecycleObserver接口,并且在對應的生命周期方法上加上注解,這個注解由Lifecycle提供,分别是:

  • @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)  對應 onCreate方法;
  • @OnLifecycleEvent(Lifecycle.Event.ON_START) 對應 onStart方法;
  • @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) 對應 onResume方法;
  • @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) 對應 onPause方法;
  • @OnLifecycleEvent(Lifecycle.Event.ON_STOP) 對應 onStop方法;
  • @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) 對應onDestroy 方法;
  • @OnLifecycleEvent(Lifecycle.Event.ON_ANY)  是以事件都執行。
public class ActivityLifeObserver implements LifecycleObserver {

    private static final String TAG = "ActivityLifeObserver";

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void onCreate() {
        Log.i(TAG, "onCreate()");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onStart() {
        Log.i(TAG, "onStart()");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
        Log.i(TAG, "onResume()");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause() {
        Log.i(TAG, "onPause()");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onStop() {
        Log.i(TAG, "onStop()");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
        Log.i(TAG, "onDestroy()");
    }
}      

        2、讓Activity或者Fragment實作LifecycleOwner接口,注冊監聽,并且在onDestory方法中登出監聽。

public class MainActivity extends AppCompatActivity implements LifecycleOwner {

    private LifecycleRegistry mLifecycleRegistry;
    private ActivityLifeObserver mActivityLifeObserver;

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

        mLifecycleRegistry = new LifecycleRegistry(this);
        // 注冊需要監聽的 Observer
        mActivityLifeObserver = new ActivityLifeObserver();
        mLifecycleRegistry.addObserver(mActivityLifeObserver);
    }

    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLifecycleRegistry.removeObserver(mActivityLifeObserver);
    }
}      

        列印結果如下:

Android Architecture Components應用架構元件實戰

二、LiveData

         用于資料的處理傳遞,它能夠儲存資料和Activity或者Fragment的生命周期同步,通常中一般使用他的實作類MutableLiveData,建立MutableLiveData需要提供一個泛型,常用的方法:

  • setValue:用于設定資料,在主線程執行。
  • postValue:用于設定資料,在子線程執行。
  • getValue:用于擷取資料。
  • observe:觀測LiveData設定的資料變化,基于觀察者設計模式,和生命周期進行綁定。        
public MutableLiveData<ProductBean> mLiveData = new MutableLiveData<>();

public void setProduct(ProductBean bean) {
    mLiveData.setValue(bean);
}

public ProductBean getProduct() {
    return mLiveData.getValue();
}      

        observe方法的源碼如下:

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    if (existing != null && !existing.isAttachedTo(owner)) {
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        return;
    }
    owner.getLifecycle().addObserver(wrapper);
}      

        可以看出observe方法添加了一個注解,表明工作在主線程,然後判斷目前Activity或者Fragment是否被銷毀,如果onDestory,則不會執行添加觀察者。否則的話,将目前的Activity或者Fragment和observe包裝成LifecycleBoundObserver ,然後再通過addObserver添加觀察者,和生命周期進行一個關聯。

        在設定資料的時候僅需要調用setProduct方傳進bean對象,擷取資料的時候可以使用getProduct進行擷取,在需要更新UI的地方調用observe方法進行更新,在這塊可能看不出來LiveData的優勢,一般情況下LiveData适合ViewModle相結合進行使用,ViewModle請看下面。

三、ViewModle

        ViewModel用來存儲和管理UI相關的資料,可于将一個Activity或Fragment元件相關的資料邏輯抽象出來,并能适配元件的生命周期,可用于在Activity或Fragment間共享資料,它可以使 ViewModel 以及 ViewModel 中的資料在螢幕旋轉或配置更改引起的 Activity 重建時存活下來, 重建後資料可繼續使用。

1、ViewModle的建立

        ViewModle的建立繼承自AndroidViewModel或者ViewModle,差別在于AndroidViewModel是ViewModle的子類,提供了getApplication的方法。

public class MyViewModle extends AndroidViewModel {
    public MutableLiveData<ProductBean> mLiveData = new MutableLiveData<>();
    public MutableLiveData<Throwable> mLiveDataThrowable = new MutableLiveData<>();
    public MutableLiveData<String> mLiveDataString = new MutableLiveData<>();

    public void setProduct(ProductBean bean) {
        mLiveData.setValue(bean);
    }

    public ProductBean getProduct() {
        return mLiveData.getValue();
    }

    public void setError(Throwable e) {
        mLiveDataThrowable.setValue(e);
    }

    public void setComplete(String complete) {
        mLiveDataString.setValue(complete);
    }
}      

2、資料的設定

        資料的設定配合LiveData的方法在需要的地方進行設定。首先需要擷取ViewModle類,ViewModle類的擷取不是通過new關鍵字建立,而是通過ViewModelProvider提供的:

MyViewModle = ViewModelProviders.of((FragmentActivity) activity).get(MyViewModle.class);      

        進而通過ViewModle執行個體對象可以調用建立的相關方法,進行資料設定。代碼案例如下:

getInatance().create(ProductInterface.class).subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<ProductBean>() {

            @Override
            public void onNext(ProductBean productBean) {
                viewModle.setProduct(productBean);
            }

            @Override
            public void onCompleted() {
                viewModle.setComplete("請求完畢");
            }

            @Override
            public void onError(Throwable e) {
                viewModle.setError(e);
            }
        });      

3、更新UI

        使用ViewModle更新UI會主動的監控Data的變化,當Data變化的時候會通知到observe,并且和生命周期綁定,不用擔心當Activity或者Fragment被銷毀的時候擷取不到對象或者持有引用導緻的空指針和記憶體洩漏,這一點非常的好。更新UI同樣也需要擷取ViewModle類,需要ViewModle類中的LiveData提供的observe方法,需要兩個參數,一個是目前上下文對象,另一個是一個Observer,如下:

public class MainActivity extends AppCompatActivity {

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

        MyViewModle viewModle = ViewModelProviders.of(this).get(MyViewModle.class);
        viewModle.mLiveData.observe(this, mObserverProductBean);
        viewModle.mLiveDataString.observe(this, mObserverString);
        viewModle.mLiveDataThrowable.observe(this, mObserverThrowable);

    }

    /**
     * 加載資料成功
     */
    Observer mObserverProductBean = new Observer<ProductBean>() {
        @Override
        public void onChanged(@Nullable ProductBean parse) {
            List<ProductBean> list = parse.getList();
        }
    };
    /**
     * 加載資料完成
     */
    Observer mObserverString = new Observer<String>() {
        @Override
        public void onChanged(@Nullable String s) {
            Log.e("TAG", s);
        }
    };
    /**
     * 加載資料錯誤
     */
    Observer mObserverThrowable = new Observer<Throwable>() {
        @Override
        public void onChanged(@Nullable Throwable throwable) {
            Log.e("TAG", throwable.getMessage());
        }
    };
}      

        至此,Lifecycle,LiveData,ViewModel 就介紹完畢,還剩下一個Room資料庫,他可以和Lifecycle,LiveData,ViewModel三者進行搭配使用,也相當友善,但是可供Android選中的第三方的資料庫太多LitePal、GreenDao、DBFlow、realm等等,目前項目中也沒有更改資料庫的計劃,是以也沒有深究,在此不做介紹了。