UML图
图解关键点
viewModel为什么能在屏幕旋转的时候,保存数据?
屏幕旋转,如果没有在 AndroidManifest.xml 配置
android:configChanges="orientation|screenSize"
,那么 Acitivity 会被销毁,重新初始化,产生新的 Activity 实例。Activity 销毁时 ActivityThread#performDestroyActivity,把数据保存到 ActivityClientRecord。内部调用 onRetainNonConfigurationInstance() ,创建 NonConfigurationInstances 对象,保存 viewModelStore。
Activity 重建完成 ActivityThread#performLaunchActivity,把数据传递到新的activity。
新的 ComponentActivity 获取 viewModelStore 时候调用 getViewModelStore() 方法,内部调用 getLastNonConfigurationInstance() 获取步骤3保存的对象里面的 viewModelStore。
viewModel 是什么时候初始化的?
通过
val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
获取对象。其中 ViewModelProvider 起到工厂的作用,生成 viewModel 对象,并把对象保存到 ViewModelStore 里面。之前如果已经保存了,就直接在 ViewModelStore 取。ViewModelStore(内部存放一个map) 在 ComponentActivity 里面初始化,是其中的全局变量,初始化的时候先从 getLastNonConfigurationInstance() 获取,如果没有,再自己创建。
viewModel 是什么时候销毁的?
ComponentActivity 里面会在构造方法,通过 getLifecycle().addObserver 注册观察者,在 onDestroy 时,非屏幕旋转导致的场景,会销毁。
viewModel 持用context吗?会内存泄漏吗?
不持有,不会导致context泄漏。