2017Google io大会上,关于android的消息,除了android o,kotlin,还有一个新的架构,componets。对于架构本身的介绍网上已经有很多了,我主要简单分析一下官方提供的demo,毕竟会写代码才是王道。
首先还是补充一个componets的基本知识:架构图如下:
需要理解的组件:ViewModel,LiveData。
LiveData是一个用于持有数据并支持数据可被监听(观察)。和传统的观察者模式中的被观察者不一样,LiveData是一个生命周期感知组件,因此观察者可以指定某一个LifeCycle给LiveData,并对数据进行监听。LiveData通过setValue方法更新数据并通知观察者,观察者一般为UI层的activity或fragment,LiveData通过observe方法在其中注册。
ViewModel将数据从UI中分离出来。并且当Activity或Fragment重构的时候,ViewModel会自动保留之前的数据并给新的Activity或Fragment使用。因为使用到Application和context,例子中使用的是AndroidViewModel,其用法一样,在UI中注册即可,例如:
final ProductListViewModel viewModel =
ViewModelProviders.of(this).get(ProductListViewModel.class);
先看demo中的BasicSample。结构如下:
其中Activity,Fragment,ui包与viewmodel交互,viewmodel与数据库(db包)交互。
可以看出,demo一共有两个界面,一个是ProductList,一个是Product。两个界面都用到了RecyclerView,所以有一个ProductAdapter,一个CommentAdapter。而ProductClickCallBack与CommentClickCallBack只是处理回调事件,在Adapter中与item绑定。在ProductFragment中,除了初始化组件外,主要绑定了ViewModel和其中的LiveData,看代码:
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ProductViewModel.Factory factory = new ProductViewModel.Factory(
getActivity().getApplication(), getArguments().getInt(KEY_PRODUCT_ID));
//初始化ViewModel,ViewModel的生命周期与Fragment无关
final ProductViewModel model = ViewModelProviders.of(this, factory)
.get(ProductViewModel.class);
mBinding.setProductViewModel(model);
subscribeToModel(model);
}
private void subscribeToModel(final ProductViewModel model) {
// Observe product data
// liveData的监听绑定 product
model.getObservableProduct().observe(this, new Observer<ProductEntity>() {
@Override
public void onChanged(@Nullable ProductEntity productEntity) {
model.setProduct(productEntity);
}
});
// Observe comments
//liveData的监听绑定 comment
model.getComments().observe(this, new Observer<List<CommentEntity>>() {
@Override
public void onChanged(@Nullable List<CommentEntity> commentEntities) {
if (commentEntities != null) {
mBinding.setIsLoading(false);
mCommentAdapter.setCommentList(commentEntities);
} else {
mBinding.setIoading(true);
}
}
});
}
ViewModel与数据库交互,利用LiveData。如代码:
mObservableProducts = Transformations.switchMap(databaseCreated,
new Function<Boolean, LiveData<List<ProductEntity>>>() {
@Override
public LiveData<List<ProductEntity>> apply(Boolean isDbCreated) {
if (!Boolean.TRUE.equals(isDbCreated)) { // Not needed here, but watch out for null
//noinspection unchecked
return ABSENT;
} else {
//noinspection ConstantConditions
//mObservableProducts使用setValue方法更新数据库中的数据,并
//通知观察者
return databaseCreator.getDatabase().productDao().loadAllProducts();
}
}
});
BasicSample比较简单,只有三层,ui,viewmodel,db。相比MVP,性能要好些,并且同样实现了解耦,模型驱动。虽有一定的学习成本,还是值得一试的。