大家都知道在Android开发中,一个好的Android架构能为项目带来极大的遍历,对于版本发布,后期维护等有着极为重要的地位,可以说架构是APP可持续发展的灵魂。在Android开发中也涌现出了很多优秀的架构,从早期的MVC到现在的MVP,MVVM等,Android架构一直在不停的演进。有鉴于此,google也终于在2017年的IO开发大会上推出了Android Architecture Components来帮助Android开发者构建更好的app架构。
当然详情可以参考下面这边文章
https://developer.android.com/topic/libraries/architecture/guide.html
Android Architecture Components 主要包括以下几个组件:
Lifecycles
生命周期管理(Lifecycles)组件,帮助开发者创建 “可感知生命周期的” 组件,让其自己管理自己的生命周期,从而减少内存泄露和崩溃的可能性。生命周期库是其他架构组件(如 LiveData)的基础。
android.arch.lifecycle 包提供了类和接口允许你构建生命周期感知(lifecycle-aware)的组件——可以基于当前activity或fragment生命周期自动调节它们的行为的组件。
了解更多 Lifecycles 相关内容:
https://developer.android.google.cn/topic/libraries/architecture/lifecycle.html
LiveData
LiveData 是一款基于观察者模式的可感知生命周期的核心组件。LiveData 为界面代码 (Observer)的监视对象 (Observable),当 LiveData 所持有的数据改变时,它会通知相应的界面代码进行更新。同时,LiveData 持有界面代码 Lifecycle 的引用,这意味着它会在界面代码(LifecycleOwner)的生命周期处于 started 或 resumed 时作出相应更新,而在 LifecycleOwner 被销毁时停止更新。通过 LiveData,开发者可以方便地构建安全性更高、性能更好的高响应度用户界面。
了解更多 LiveData 相关内容:
https://developer.android.google.cn/topic/libraries/architecture/livedata.html
ViewModel
ViewModel 将视图的数据和逻辑从具有生命周期特性的实体(如 Activity 和 Fragment)中剥离开来。直到关联的 Activity 或 Fragment 完全销毁时,ViewModel 才会随之消失,也就是说,即使在旋转屏幕导致 Fragment 被重新创建等事件中,视图数据依旧会被保留。ViewModels 不仅消除了常见的生命周期问题,而且可以帮助构建更为模块化、更方便测试的用户界面。
了解更多 ViewModel 相关内容:
https://developer.android.google.cn/topic/libraries/architecture/viewmodel.html
Room
Room是一个基于SQLite对象映射层ORM的数据库框架,类似于greenDao等。 Room 可以和 LiveData 集成在一起,提供可观测数据库并感知生命周期的对象。Room 集简洁、强大和可靠性为一身,在管理本地储存上表现卓越。由于Room是官方推出的,还是有必要了解。
了解更多 Room 相关内容:
https://developer.android.google.cn/topic/libraries/architecture/room.html
以上只是简单的介绍Android架构组件的相关内容,我们先学会怎么使用,然后再深入的分析。
想要阅读Android架构组件的Demo,可以参考官方推出一个示例工程
https://github.com/googlesamples/android-architecture-components 参考其BasicSample即可。
但是由于官方的Demo中使用了DataBinding,因此个人觉得Demo还是稍微有些冗余。可以来一个更简洁的Demo来演示各个组件的用法。
1 将android support组件升级到26.1.0版本以后,保证fragment activity等组件实现了Lifecycles等接口
2 build.gradle配置文件下添加以下依赖
由于google已经正式发布了Android Architecture Components 1.0版本,我们就可以添加以下依赖了
compile "android.arch.lifecycle:runtime:1.0.0"
compile "android.arch.lifecycle:extensions:1.0.0"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0"
compile "android.arch.persistence.room:runtime:1.0.0"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
testCompile "android.arch.persistence.room:testing:1.0.0"
下面我们分别来看UI下的代码:
ArchitectureActivity.java
/**
* @author Created by qiyei2015 on 2018/1/13.
* @version: 1.0
* @email: [email protected]
* @description:
*/
public class ArchitectureActivity extends BaseActivity {
/**
* 标题栏
*/
private CommonTitleBar mTitleBar = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initData();
if (savedInstanceState == null) {
ProductListFragment fragment = new ProductListFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment, fragment, ProductListFragment.TAG).commit();
}
initView();
}
@Override
protected void initContentView() {
setContentView(R.layout.activity_architecture);
}
@Override
protected void initView() {
mTitleBar = new CommonTitleBar.Builder(this)
.setTitle("Android 架构组件")
.setRightText("维护中")
.build();
}
@Override
protected void initData() {
}
@Override
public void onClick(View v) {
}
}
代码很简单,主要是UI部分的显示逻辑,显示标题栏和显示一个fragment即可。接下来看fragmeng 的逻辑
/**
* @author Created by qiyei2015 on 2018/1/13.
* @version: 1.0
* @email: [email protected]
* @description:
*/
public class ProductListFragment extends Fragment {
public static final String TAG = "ProductListFragment";
private TextView mTextView;
private RecyclerView mRecyclerView;
private ProductListViewModel mViewModel;
ProductAdapter productAdapter;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = ViewModelProviders.of(this).get(ProductListViewModel.class);
mViewModel.init("2");
mViewModel.getProducts("id").observe(this, new Observer>() {
@Override
public void onChanged(@Nullable List products) {
productAdapter.setDatas(products);
mTextView.setText("测试 :" + products.size());
}
});
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_product_list,container,false);
mTextView = rootView.findViewById(R.id.tv1);
mRecyclerView = rootView.findViewById(R.id.recycler_view);
mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mViewModel.setTest("2");
}
});
productAdapter = new ProductAdapter(getContext(),new ArrayList<>(),R.layout.recyclerview_item);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.setAdapter(productAdapter);
productAdapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void click(View view, Product product,int position) {
ToastUtil.showShortToast(product.getName());
}
});
return rootView;
}
}
fragment中持有ProductListViewModel的引用,同时会对ProductListViewModel做初始化,另外获取到了LiveData,使其注册了一个观察者,监听当LiveData中数据改变时通知UI层
接下来看ViewModel中代码。
/**
* @author Created by qiyei2015 on 2018/1/13.
* @version: 1.0
* @email: [email protected]
* @description:
*/
public class ProductListViewModel extends ViewModel {
private String mId;
private ProductRepository mRepository;
public void init(String id){
mId = id;
mRepository = new ProductRepository(id);
}
public LiveData> getProducts(String id){
return mRepository.getProducts(id);
}
public void setTest(String id){
mRepository.setTest(id);
}
}
很简单,持有ProductRepository 的引用,同时将数据的操作转发给ProductRepository 。
ProductRepository 中主要负责组织管理数据,这里我并没有增加网络获取数据或者从Room中获取数据的操作,个人觉得这一块的代码相对来说比较单一。
/**
* @author Created by qiyei2015 on 2018/1/13.
* @version: 1.0
* @email: [email protected]
* @description:
*/
public class ProductRepository {
private MutableLiveData> mProducts;
List list = new ArrayList<>();
public ProductRepository(String id) {
mProducts = new MutableLiveData<>();
}
/**
* @return {@link #mProducts}
*/
public MutableLiveData> getProducts(String id) {
for (int i = 0 ;i < 10;i++){
list.add(new Product("" + i,"name:" + i));
}
mProducts.setValue(list);
return mProducts;
}
public void setTest(String id){
list.add(new Product("" + id,"name:" + id));
mProducts.setValue(list);
ToastUtil.showLongToast("id");
}
}
这样的一个Demo除了Room的使用没有增加到其中外,其他的都实现了。并且架构还是比较清晰。整个架构和官方的Demo的架构并无明显的区别。
源码参考:
github https://github.com/qiyei2015/EssayJoke appdemo中架构部分
总体来看,Android架构组件的使用较为简单,并且将架构做了分层,架构清晰,另外对于Activity,Fragment生命周期的管理也非常出色。但是官方给的Demo实在过去简单,将Android 架构组件用于大项目中还需要一定的实践经验。个人觉得这个架构组件特别适用于UI部分的解耦。对于Android纵向架构的梳理还是不错的,类似于MVP。如果再加上组件化,插件化的横向解耦,那么对于Android整个架构的影响还是比较不错的,值得开发者去学习和尝试。
下一期将会深入解读Android架构组件的设计以及关于这方面的思考。