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

相关推荐
子云心15 天前
Android Jetpack 系列(七)App Startup 启动优化
android·android jetpack·jetpack·initializer·startup·appstartup
撩得Android一次心动23 天前
Android DataBinding 全面解析【使用篇】
android·jetpack·databinding
特立独行的猫a1 个月前
从XML到Compose的UI变革:现代(2026)Android开发指南
android·xml·ui·compose·jetpack
撩得Android一次心动1 个月前
Android LiveData 全面解析:使用Java构建响应式UI【使用篇】
android·livedata·jetpack
氦客2 个月前
Android Compose : 传统View在Compose组件中的等价物
android·compose·jetpack·对比·传统view·等价物·compose组件
zFox2 个月前
四、ViewModel + StateFlow + 状态持久化
kotlin·stateflow·viewmodel
csdn12259873363 个月前
JetPack Compose 入门先搞清楚
android·compose·jetpack
m0_527653904 个月前
NVIDIA Orin NX使用Jetpack安装CUDA、cuDNN、TensorRT、VPI时的error及解决方法
linux·人工智能·jetpack·nvidia orin nx
江太翁5 个月前
Room 概要
kotlin·room·jetpack
氦客5 个月前
Android Compose中的附带效应
android·compose·effect·jetpack·composable·附带效应·side effect