ViewModel

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的数据。

相关推荐
大福是小强1 个月前
005-Kotlin界面开发之程序猿初试Composable
kotlin·界面开发·桌面应用·compose·jetpack·可组合
sziitjin2 个月前
Jetpack Compose 02 Compose + ViewModel UI和数据逻辑分离
android·compose·viewmodel
challenge51all4 个月前
ViewModel(8)单元测试
android·单元测试·jetpack·viewmodel
challenge51all4 个月前
Compose(7)交互和动画
compose·jetpack
challenge51all4 个月前
Compose(10)单元测试
单元测试·compose·jetpack
heeheeai6 个月前
安卓 jetpack compose
android·jetpack
Just_Paranoid7 个月前
Android 架构组件面试问答
android·架构·kotlin·组件·jetpack
xiangxiongfly9158 个月前
Jetpack Compose简介
compose·jetpack
xiangxiongfly9158 个月前
Compose和Android View相互使用
compose·jetpack·copmpose使用view·view使用compose