一、前言
ViewModel 可观察数据存储类属于谷歌在2018推出Android jetpack(外网)其中的软件架构组件中的一个。在谷歌开发者网站有详细介绍ViewModel(外网)。
全文就一句话
ViewModel核心:存储和管理界面相关的数据
理解此文前建议简单阅读Lifecycle,理解生命周期组件
二、ViewModel
谷歌爸爸介绍
ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel类让数据可在发生屏幕旋转等配置更改后继续存在。
ViewModel使用场景
ViewModel的使用主要是独立存储和管理界面相关的数据,把界面数据分离出来用ViewModel来管理。
比如Activity/Fragment要重复的打开关闭,若数据时一些网络请求什么的,不必每次创建都去异步请求,请求一次,ViewModel统一管理就好。
为什么例子中的ViewModel都是管理LiveData
ViewModel管理的数据可以是多种,只不过我们更多的管理LiveData,因为LiveData有观察者模式+生命周期特性,方便数据变化时去改变界面。所以他们形影不离。
因为你的目的就是数据变化了去更改UI,如果不用LiveData,就普通的一个String,你得加个回调监听或者别的方式通知到UI你数据已经变化了,你得判断空,判断context是否还存在,等等。思想上他们是相同的。
三、详细介绍
ViewModel总结来就是下面
- 1、生命周期
- 2、Fragment间共享数据
- 3、使用场景
3.1、生命周期
ViewModelProvider.Factory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication());
ViewModelProvider viewModelProvider = new ViewModelProvider(this, factory);
viewModel = viewModelProvider.get(MyViewModel.class);
- ViewModel创建是:传递给ViewModelProvider一个Lifecycle(代码中的this)+工厂模式来创建
- ViewModel创建后随着Lifecycle一起一直存在,直到Lifecycle消失,即Activity/Fragement销毁(销毁时,Lifecycle消失)。
-
ViewModel完全依赖于Lifecycle的,所以ViewModel具有生命周期感知能力
来看谷歌爸爸贴出来的一张图
3.2、Fragment共享数据
我们经常在一个Activity写多个Fragment,他们之间经常切换共享数据。使用ViewModel就很方便。
public class MyViewModel extends ViewModel {
MutableLiveData title;
public MutableLiveData getTitle() {
return title;
}
}
public class MasterFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewModelProvider.Factory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication());
ViewModelProvider viewModelProvider = new ViewModelProvider(getActivity(), factory);
viewModel = viewModelProvider.get(MyViewModel.class);
}
}
public class DetailFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewModelProvider.Factory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication());
ViewModelProvider viewModelProvider = new ViewModelProvider(getActivity(), factory);
viewModel = viewModelProvider.get(MyViewModel.class);
}
}
- 在Activity范围下,ViewModel拿到的对象实例是同一个。所以他们很方便的就能共享数据,而不需要我们去操作Activity
- 各个Fragment之间没有影响,一个关闭不会影响另一个
- 我们拿到数据也快,开启一个新的Fragment,ViewModel没有被销毁,拿到实例就可显示
3.3、应用场景
- ViewModel + LiveData 管理UI数据
- Fragment之间共享数据
- VIewModel + LiveData+Room 数据加载器
- ViewModel + LiveData + DataBinding 绑定数据自动更新
分别说下这几个控件
Lifecycle:设计来独立生命周期。ViewModel和LiveData都依赖于Lifecycle,具有生命周期感知能力(本文ViewModel的体现就是一直存在直到Lifecycle销毁)。依赖它就可以不必担心生命周期存在否,UI是否显示,Activity是否在后台等逻辑。
ViewModel:它思想就是独立管理数据。把这个数据管理任务和UI分离
LiveData:存在的目的是,既然ViewModel可以很好的拆分UI和数据了,那么就需要LiveData的来优雅的更新UI,采用LiveData去更新UI,省去很多代码和逻辑耦合。
DataBinding:布局引用数据源,简化数据和UI之间的操作
Room:设计来轻量化管理sqlite,让我们更好的操作。强大且稳健。并且Room扩展返回LiveData或者Rxjava中的Publisher和Flowable或者cursor等
四、写在最后
- 整体来说ViewModel还是十分简单的一个控件。它被设计来存储和管理界面相关的数据。
- 它也是一个比较基本的控件单元,多和一些别的控件一起使用。
- 巧妙的解耦和生命周期感知能力让它简单而又强大。