前言
今天跟大家分享的是网友提供的一道字节跳动的面试真题,请看原题:
- ViewModel 是什么?
- ViewModel 为什么被设计出来,解决了什么问题?
- 说说ViewModel原理。
- ViewModel怎么实现自动处理生命周期?
- 为什么在旋转屏幕后不会丢失状态?
- 为什么ViewModel可以跟随Activity/Fragment的生命周期而又不会造成内存泄漏呢?
- ViewModelScope了解吗?
解答
ViewModel是什么?
ViewModel
是MVVM架构的一个层级,用来联系View和model之间的关系。
官方文档解释:
ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据
这里面有两个信息:
- 注重生命周期的方式。
由于ViewModel
的生命周期是作用于整个Activity的,所以就节省了一些关于状态维护的工作,最明显的就是对于屏幕旋转这种情况,以前对数据进行保存读取,而ViewModel
则不需要,他可以自动保留数据。
其次,由于ViewModel
在生命周期内会保持局部单例,所以可以更方便Activity的多个Fragment
之间通信,因为他们能获取到同一个ViewModel实例,也就是数据状态可以共享了。
- 存储和管理界面相关的数据。
ViewModel
层的根本职责,就是负责维护界面上UI的状态,其实就是维护对应的数据,因为数据会最终体现到UI界面上。所以ViewModel
层其实就是对界面相关的数据进行管理,存储等操作。
ViewModel 为什么被设计出来,解决了什么问题?
- 在
ViewModel
组件被设计出来之前,MVVM又是怎么实现ViewModel这一层级的呢?
其实就是自己编写类,然后通过接口,内部依赖实现View和数据的双向绑定。所以Google出这个ViewModel组件,无非就是为了规范MVVM
架构的实现,并尽量让ViewModel这一层级只触及到业务代码,不去关心VIew层级的引用等。然后配合其他的组件,包括livedata,databindingrang
等让MVVM架构更加完善,规范,健硕。
- 解决了什么问题呢?
1)不会因为屏幕旋转而销毁,减少了维护状态的工作
2)由于在作用域内单一实例的特性,使得多个fragment
之间可以方便通信,并且维护同一个数据状态。
3)完善了MVVM
架构,使得解耦更加纯粹。
说说ViewModel原理。
在分析ViewModel的工作原理之前,我们最好带着问题去分析。
- ViewModel如何被创建的,在什么时候被销毁?
- ViewModel的生命周期如何与组件生命周期绑定?
- 为什么Activity重建时ViewModel的数据没有丢失?
- Fragment之前如何共享ViewModel?
ViewModel的创建与销毁
ViewModel的创建
分析ViewModel的创建自然是从ViewModel初始化的地方开始。
viewModel = ViewModelProvider(this).get(TestViewModel::class.java)
ViewModel的初始化很简单,通过ViewModelProvider就可以获取到ViewModel实例。那么从这里入手开始分析ViewModel的创建过程。
第一步是先初始化了一个ViewModelProvider对象,所以我们先看下ViewModelProvider的构造方法;
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) {
this(owner.getViewModelStore(), factory);
}
从ViewModelProvider的构造方法中可以看到最终是需要两个参数ViewModelStoreOwner以及Factory。这两个参数中ViewModelStoreOwner是用来存储ViewModel对象的,Factory是用来创建ViewModel对象。这个接下来的分析中也会提到。
第二步是通过V