Google IO 2017发布Android Architecture Components,这个新的架构库旨在帮助我们设计健壮、可测试的和可维护的应用程序。AAC主要提供了Lifecycle,LiveData,ViewModel ,Room等功能,在代码中使用它会使得App架构更加健壮,避免内存泄漏和一些空指针等问题。整体的架构如下:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX9E0MiZHetNGb1IjY2x2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zNyITNyQTMxIDMzYDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
在使用这些组件前先需要在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);
}
}
打印结果如下:
二、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等等,目前项目中也没有更改数据库的计划,因此也没有深究,在此不做介绍了。