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缓存机制来看屏幕旋转的过程:
- 首次启动Activity:创建ViewModel实例,调用
fillingList(),LiveData中存入一个5元素列表。 - 屏幕旋转:Activity销毁,但ViewModel实例被
ViewModelStore缓存。 - 新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
相关产品推荐
相关产品推荐

