ViewModel 到底是啥
入门文章. 本文纯属个人见解, 请谨慎阅读.
本文回答这个问题:
Jetpack 中的 ViewModel 到底是啥, Google 希望开发者怎么用?
ViewModel
-
Google 为什么推出 ViewModel 这个东西?
从开始做 Android 开发, 就有一个问题觉得不可思议: 我只不过是把屏幕旋转了一下, 为什么我存到 Activity / Fragment 中的变量(对象\数据)就没了呢? 难道 Android 能帮我把 view 重建, 就不能帮我把这些数据保存下来?后来我们知道, 由于 Android 发生了 config change, view 的重建意思就是 Activity Fragment 等组件, 在销毁之后, Android 帮助我们重新创建了. 这是跟生命周期相关的. 然后 Android 就把数据保存的工作甩给了开发者, 告诉开发者们 你们可以用
onSaveInstanceState(outBundle: Bundle)
这个方法在组件被销毁之前保存下来, 最后当这些组件重新创建的时候, 在onCreate(savedInstanceState: Bundle?)
中读取并设置控件的值就行了.乍一看, 这没什么毛病, 人家要销毁你的组件了, 给你提供一组保存和重置数据的接口方法, 并且帮你重新创建了组件, 仁至义尽了对吧?
实际上, 作为菜鸟级开发者, 这对我来说实在有点太难了. 我还要记住这些方法名, 以及方法的参数有时候有值 有时候又没有值(onCreate 方法的传入参数, 在正常创建的时候为空, 在销毁重建恢复用户数据的时候可能不为空
). 有这时间我多想想怎么把 APP 的业务搞的更健壮不好吗?这实际上就是 Google 在了解到开发者的痛楚之后, 为广大的 Android 开发者提供的福利. (而我还是感觉 Google 可以做的更好, 这种生命周期对开发者来说最好是透明的, 开发者不用去关心什么时候 view重建了 我要重新赋值了 等等这些问题, 开发者只要做好业务实现, 其他都交给 framework, 这才是我心目中理想的框架实现)
那么为我们保存Activity 和 Fragment 状态的就是: ViewModel.
ViewModel 不同于 Activity 中的实例变量. Activity 中的实例变量在Activity发生 config change 的时候被销毁了. 而 ViewModel 对象有一个独立的生命周期. 他不会由于 Activity 的config change而销毁. 因此 ViewModel 这个对象是可以独立于 Activity 的生命周期而幸存的.
简单说就是: ViewModel 帮助开发者省去了对
onSaveInstanceState(outBundle: Bundle)
和onCreate(savedInstanceState: Bundle)
这两个方法的顾虑.
-
ViewModel 好用吗?
- 上面说了 ViewModel 的出现, 让开发者省去了对状态数据销毁和重建的顾虑.
- 那么他好用吗? 要是虽然不用考虑那两个方法了, 但是需要考虑更多的细节, 岂不是得不偿失?
- 对! 是的! 好用! 至少不会比之前难用!
-
ViewModel 怎么用?
- 很简单, 只要记住两个步骤就行:
- 原来在 Activity 或 Fragment 中创建实例变量的地方, 改成对 ViewModel 的引用
- 创建一个 ViewModel 的子类, 把原来写在 Activity 中的那些实例变量放到这个 viewModel 里面去
徒手写代码
- 创建一个 ViewModel
class MainActivityViewModel : ViewModel() {
var name: String? = null
var age: Int? = null
}
- 在 Activity 中引用
class MainActivity: AppCompatActivity() {
private lateinit var mainViewModel: MainActivityViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mainViewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
// mainViewModel.name = "chinalwb"
// 访问mainViewModel.age, 操作..
// 把 mainViewModel 的值设置到控件上
}
}
- 很简单对吧?!
- 是的.. 额! 你没说怎么恢复已经保存的数据啊
- 嗯, 你说的非常好! 我们知道在 Activity 发生 config change 而销毁重建的时候, onCreateView 是必定要执行到的. 所以我们在这个方法中对 viewModel 进行初始化和数据的访问和设定, 就完成了数据的恢复