1 主要功能
1) 引入ViewModel
compile('android.arch.lifecycle:extensions:1.0.0')
由于lifecycle.extensions内部依赖26.1.0版本的support_v7包,建议将工程中已引用的support_v7组件版本也升级到26.1.0或以上。
2) 构造数据对象
public class DemoViewModel extends ViewModel {
final public DemoData mData = new DemoData();
public DemoViewModel() {}
}
3) 获取数据
DemoData data = ViewModelProviders.of(getActivity())
.get(DemoViewModel.class)
.mData;
data.doSth();
麻烦且数据大小有限制。
同样麻烦,且有一定风险。
ViewModel同时规避了传统方法的缺点:
同为官方架构组件的LiveData,功能是监听数据变化,并回调给注册的observer。ViewModel+LiveData可以很方便的抽象出数据层和业务层,快速解耦。 下面的Demo来自官方案例。通过Demo,以及LiveData、ViewModel同处一个module,可以看出官方非常建议两者搭配使用。再配合以往的Data-Binding,可以快速搭建起一套简易的MVVM业务体系。
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public LiveData<List<User>> getUsers() {
if(users == null) {
users= new MutableLiveData<List<Users>>();
loadUsers();
}
return users;
}
private void loadUsers() {
//Do an asyncronous operation to fetch users.
}
}
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
//Create a ViewModel the first time the system calls an activity's onCreate()method.
//Re-created activities receive the same MyViewModel instance created by thefirst activity.
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this,users -> {
//update UI
});
}
}
ViewModel的生命周期与Lifecycle同步,当Activity /Fragment超出Lifecycle范围(并不是onDestroy()回调),ViewModel连同其包含的数据一起被销毁了。具体有多大呢,按照官方说法:
in the case of an activity, when it finishes, whilein the case of a fragment, when it’s detached.
Activity退栈后(Fragment则是与Activity解除关系后),ViewModel就解除引用关系,准备被系统回收了。下面这张图片更直观的展示了ViewModel的生命周期:
带着两个小问题简单的进行下源码分析:
第一部分:获取ViewModelProvider
HolderFragment.class
HolderFragment holderFragmentFor(FragmentActivity activity) {
FragmentManagerfm = activity.getSupportFragmentManager();
HolderFragment holder = findHolderFragment(fm);
if(holder != null) {
return holder;
}else {
holder = (HolderFragment)this.mNotCommittedActivityHolders.get(activity);
if(holder != null) {
return holder;
}else {
//创建HolderFragment
第一部分的职责是构建 / 查找HolderFragment,对构建过程中的异常做保护,最后返回ViewModelProvider。HolderFragment和ViewModelProvider共同持有的ViewModelStore将成为第二部分的核心;
(第二部分:获取ViewModel)
ViewModelStore.class
public class ViewModelStore {
private final HashMap<String, ViewModel> mMap = new HashMap();
第二部分职责是映射,通过类名从HashMap查找ViewModel实例。整个映射逻辑也可以简化为:通过Activity类名找ViewModel实例;
ViewModel objects are scoped to the Lifecycle passed to the ViewModelProvider when getting the ViewModel.
看到官方文档中的这句话,心想ViewModel莫非是通过同为官方架构组件的Lifecycle来管理的生命周期的? 其实并没有那么复杂,ViewModel在第一次调用ViewModelProvider.get(ViewModel.class)创建;而销毁就需要靠HolderFragment自己的onDestroy()回调:
HolderFragment.class
public void onDestroy() {
super.onDestroy(); this.mViewModelStore.clear();
}
ViewModelStore.class
public final void clear() {
Iteratorvar1 = this.mMap.values().iterator();
while(var1.hasNext()){
ViewModel vm = (ViewModel)var1.next();
vm.onCleared();
}
this.mMap.clear();
}
HolderFragment销毁后,调用ViewModelStore.clear(),清理HashMap对ViewModel对象的引用,待系统GC回收ViewModel。这也解释了创建ViewModelProvider时为什么需要HolderFragment配合,HolderFragment掌控了ViewModel的生命周期。
简述下官方架构中各组件的主要职责:
除了Room,可以感受到官方在尽力把大家从最初的MVC往MVVM引导,更加强大的官方组件将使UI-业务-数据的抽象过程变得更加简单顺滑。