ViewMode是MVVM架构模式中VM层对应的类,它的作用是存储界面数据,并和界面发生数据交互。ViewModel能感知生命周期,并且在界面由于配置问题发生重建时候,可以保持当前的数据不变。生命周期如下:
ViewMode由ViewModeProvider创建,然后把创建的ViewModel放入ViewModelStore内部。
MainActivity:
java
val viewModel : CalendarViewModel by lazy {
ViewModelProvider(this, ViewModelProvider.NewInstanceFactory())
.get(CalendarViewModel::class.java)
}
ViewModelProvider:
java
public open operator fun <T : ViewModel> get(key: String, modelClass: Class<T>): T {
return try {
factory.create(modelClass, extras) //创建viewModel
} catch (e: AbstractMethodError) {
factory.create(modelClass)
}.also { store.put(key, it) } //把ViewModel放入Store的hashmap中
}
当配置改变导致的重建时,ViewModelStore不会被重建或者清除,因此ViewModel也不会重建,这主要是因为viewModelStore是被存在ActivityClientRecord中,Activity的销毁不会影响它。
从源代码看看:
Activity被修改配置后(如屏幕旋转)后,导致的销毁重建,会调用onRetainNonConfigurationInstance这个函数,viewModelStore就是在这里恢复的:
java
final override fun onRetainNonConfigurationInstance(): Any? {
var viewModelStore = _viewModelStore
if (viewModelStore == null) {
// ViewModelStore from our last NonConfigurationInstance
val nc = lastNonConfigurationInstance as NonConfigurationInstances?
if (nc != null) {
viewModelStore = nc.viewModelStore
}
}
}
这里还要获取到上一次的非配置实例lastNonConfigurationInstance,它就是通过ActivityThread中的attach方法,传递给Activity内部的:
java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
activity.attach(...,r.lastNonConfigurationInstances,...);
}
所以从最后看出,viewModel的数据实际是保存在ActivityClientRecord中的。
ViewModel感知生命周期,是通过Lifecycle去实现的,如下:
java
lifecycle.addObserver(
LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_DESTROY) {
if (!isChangingConfigurations) { //不是配置改变,才会清除viewmodelStore
viewModelStore.clear()
}
}
}
)
这里也可以看到,当正常的界面销毁(非配置改变导致的销毁)会调用到ViewModelStore的clear方法,清除ViewModel的数据。