ViewModel.md
ViewModel
- 可以提供和管理UI界面数据。(将加载数据与数据恢复从 Activity or Fragment中解耦)
- 可感知生命周期的组件。
- 不会因配置改变(Configuration change)而销毁。
- 可以配合 LiveData 使用。
- 多个 Fragment 可以共享同一 ViewModel。
Configuration change的情况:
- 屏幕旋转
Activity重建:
- 屏幕旋转
- 用户手动切换系统语言
- 系统内存不足,应用在后台被系统杀掉,然后用户再进入应用
系统杀后台跟屏幕旋转最大的不同是:杀后台Activity不会走onDestory()和onRetainCustomNonConfigurationInstance()方法。
对于我个人而言,ViewModel是数据与View层还有Model层分离的手段,为什么要分离呢?第一,层次化。使得数据、视图的分层更加合理,方便管理和扩张。第二,脱离声明周期。以往数据没有分离,数据是与视图绑定的,众所周知,视图的声明周期极其复杂,数据的管理也会受到影响,所以分离就极其重要了。
- 管理数据,把VIEW中的数据独出来,单独进行管理
- 管理数据的保存与恢复,比如屏幕转动,用户点回退按钮,或切换语言等操作
- 可以很方便的监听到UI上的数据变化
- 主要和LiveData与Room组合使用
注意:ViewModel只是用来管理UI的数据的,千万不要让它持有View、Activity或者Fragment的引用(小心内存泄露)。
ViewModel数据恢复原理
当屏幕旋转或者切换系统语言时,Activity 生命周期从销毁再重建,但是ViewModel里面的变量值不受到影响,说明ViewModel中的变量在屏幕旋转前进行了存储,在屏幕旋转后又进行了恢复。
里面的原理是怎么实现的呢?
分析入口://获取viewModel
model = ViewModelProviders.of(getActivity()).get(NameViewModel.class);
ViewModelProviders.of():
- 保存了ViewModelStore和Factory并返回ViewModelProvider
- 参数1:getViewModelStore()方法中
从Activity的NonConfigurationInstances中取ViewModelStore,取不到就new一个
参数2:Factory中反射生成ViewModel实例
ComponentActivity
- onRetainNonConfigurationInstance()保存状态 转屏时自动调用
- getLastNonConfigurationInstance()恢复状态
Activity在横竖屏切换时悄悄保存了viewModelStore,放到了NonConfigurationInstances实例里面,横竖屏切换时保存了又恢复了回来,相当于ViewModel实例就一直在,也就避免了横竖屏切换时的数据丢失.
如果想要系统内存不足,杀掉后台,App再次回到前台,之前的数据进行恢复,应该怎么处理?
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LT的编程笔记!