Moosphan / Android-Daily-Interview

:pushpin:每工作日更新一道 Android 面试题,小聚成河,大聚成江,共勉之~

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2019-12-06:ViewModel的出现是为了解决什么问题?并简要说说它的内部原理?

Moosphan opened this issue · comments

2019-12-06:ViewModel的出现是为了解决什么问题?并简要说说它的内部原理?

viewModel出现为了解决什么问题?
看下viewModel的优点就知道了:
1.对于activity/fragment的销毁重建,它们内部的数据也会销毁,通常可以用onSaveInstanceState()防法保存,通过onCreate的bundle中重新获取,但是大量的数据不合适,而vm会再页面销毁时自动保存并在页面加载时恢复。
2.对于异步获取数据,大多时候会在页面destroyed时回收资源,随着数据和资源的复杂,会造成页面中的回收操作越来越多,页面处理ui的同时还要处理资源和数据的管理。而引入vm后可以把资源和数据的处理统一放在vm里,页面回收时系统也会回收vm。加上databinding的支持后,会大幅度分担ui层的负担。
内部原理:
vm内部很简单,只有一个onClean方法。
vm的创建一般是这样ViewModelProviders.of(getActivity()).get(UserModel.class);
1.ViewModelProviders.of(getActivity())
在of方法中通过传入的activity获取构造一个HolderFragment,HolderFragment内有个ViewModelStore,而ViewModelStore内部的一个hashMap保存着系统构造的vm对象,HolderFragment可以感知到传入页面的生命周期(跟glide的做法差不多),HolderFragment构造方法中设置了setRetainInstance(true),所以页面销毁后vm可以正常保存。
2.get(UserModel.class);
获取ViewModelStore.hashMap中的vm,第一次为空会走创建逻辑,如果我们没有提供vm创建的Factory,使用我们传入的activity获取application创建AndroidViewModelFactory,内部使用反射创建我们需要的vm对象。

存储UI数据

在Activity中有onRetainNonConfigurationInstance和getLastNonConfigurationInstance这两个方法,主要是借助于系统的机制,保存一些持续性的数据
在最新的ViewModel的版本中,已经将ViewModelStore从 Fragment(setRetainInstance(true))中移至Actiivity的上述两个方法中保存了

ViewModel主要就是为了解决内存泄漏并且保存UI数据的问题,开发者应该只在ViewModel中保存与Context无关的UI数据

ViewModel 类:辅助程序类,用来保存应用UI数据,负责为界面准备数据。它会在配置变更后继续存在。将应用所有的UI数据保存在 ViewModel 中,而不是 Activity 中,这样就能确保数据不会受到配置变更的影响。
内部原理:利用 Activity 的 onRetainNonConfigurationInstance() 方法在旋转屏幕时保存 ViewModelStore 实例,并在重新创建时重新赋值。