You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android ViewModel配置变更处理原理及代码实例疑问

ViewModel配置变更缓存机制与你的代码问题解析

一、ViewModel处理配置变更的核心原理

ViewModel的设计初衷就是让数据在Activity/Fragment的配置变更(如屏幕旋转)中得以保留,幕后依赖系统的ViewModelStore缓存机制:

  • 当发生配置变更时,系统会销毁当前Activity实例,但不会销毁对应的ViewModelStore——这个Store专门用于存储当前组件关联的ViewModel实例。
  • 新创建的Activity实例会复用同一个ViewModelStore,当你通过ViewModelProvider(this)获取ViewModel时,系统会优先从Store中查找已有实例,只有Store中没有对应类型的ViewModel时,才会创建新实例。
  • 这就保证了配置变更前后,你拿到的是同一个ViewModel实例,其内部的LiveData等数据自然也会保留。

二、你的代码为什么没实现列表大小递增的预期

先看你的fillingList()方法:

fun fillingList(){
    var Integerlist = mutableListOf<Int>(1,2,3,4,5)
    list.setValue(Integerlist)
}

这里每次调用都会创建一个全新的包含5个元素的列表,然后通过setValue直接替换LiveData中原有的列表,而非在原有列表基础上追加元素。

结合ViewModel缓存机制来看屏幕旋转的过程:

  1. 首次启动Activity:创建ViewModel实例,调用fillingList(),LiveData中存入一个5元素列表。
  2. 屏幕旋转:Activity销毁,但ViewModel实例被ViewModelStore缓存。
  3. 新Activity实例创建:通过ViewModelProvider(this)获取到之前缓存的同一个ViewModel实例,再次调用fillingList(),此时会把LiveData中的现有列表替换成新的5元素列表,而非追加,所以列表大小始终保持5。

三、修正方案(实现列表大小递增)

如果要实现每次旋转后列表大小增加5,需要修改fillingList(),在原有列表的基础上添加元素:

fun fillingList(){
    // 获取当前LiveData中的列表,为空则创建新列表
    val currentList = list.value ?: mutableListOf()
    // 追加新元素
    currentList.addAll(listOf(1,2,3,4,5))
    // 更新LiveData
    list.setValue(currentList)
}

这样每次调用fillingList()都会在ViewModel保留的原有列表上添加元素,屏幕旋转后复用同一个ViewModel实例,列表自然会持续递增。

内容的提问来源于stack exchange,提问作者mtfuji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:07:25