Android Jetpack库剖析之ViewModel组件篇 前言 今天让我们一起去探究一下ViewModel的实现原理,描述的不对或不足还请海涵,仅作为参考 ViewModel简介 ViewModel是一个可感知Activity或Fragment生命周期的一个架构组件,当视图销毁,数据也会被清除,所以它的本质就
前言
今天让我们一起去探究一下ViewModel的实现原理,描述的不对或不足还请海涵,仅作为参考
ViewModel简介
ViewModel是一个可感知Activity或Fragment生命周期的一个架构组件,当视图销毁,数据也会被清除,所以它的本质就是用来存储与视图相关的数据,让视图显示控制与数据分离,即使界面配置发生改变数据也不会被销毁,通常配合LiveData使用
ViewModel用法
1,使用ViewModelProvider获取ViewModel实例
2,订阅VIewModel的LiveData
3,调用ViewModel的方法
构造ViewModelProvider过程做了什么
1,当我们创建ViewModelProvider的时候需要传入一个ViewModelStoreOwner对象,ViewModelStoreOwner是负责提供ViewModelStore对象的, 而ComponentActivity实现了这个接口,所以我们默认传当前的Activity即可
2,首先判断是否有默认的ViewModel工厂,如果没有就创建一个Factory
3,Factory是用来创建ViewModel的,ViewModelStore是用来存储ViewModel的
调用get()方法是如何构建ViewModel
1,当我们调用get()方法时会先获取类名,然后生成一个唯一的key
2,先通过key到ViewModelStore中取ViewModel,如果不为空代表已经创建过这个ViewModel的实例,直接返回这个实例
3,如果为空就通过工厂利用java反射机制创建一个实例,通过键值对形式保存到ViewModelStore中,返回实例,看到这里是不是对为什么多个fragment可以共享同一个ViewModel的疑问豁然开朗了,因为Fragment是依附于Activity之上的,在我们构建ViewModelProvider的时候传入同一个Activity,那么ViewModelProvider得到的ViewModelStore是同一个,在我们调用get()方法时就能通过key到ViewModelStore中取到同一个ViewModel实例,说白了就是共用Activity的ViewModel
Activity配置发生改变如何缓存ViewModelStore
1,当我们切换横竖屏的时候,ActivityThread会接收到RELAUNCH_ACTIVITY消息,会调用自身的handleRelaunchActivityInner(),这个方法里面有一个参数r,类型是ActivityClientRecord,我们每打开一个Activity,ActivityThread就会生成这么个对象来记录我们打开的Activity并保存起来
2,handleRelaunchActivityInner()这个方法里调用了handleDestroyActivity()方法去销毁我们的Activity
3,handleDestroyActivity()则直接调用了performDestroyActivity()方法去销毁Activity,核心部分就是调用了Activity的retainNonConfigurationInstances()方法获取了配置实例并复制给了ActivityClientRecord,把NonConfigurationInstances实例保存起来
4, 通过查阅源码,一层一层的往下剖析,ActivityThread是通过这样的调用链来获取我们的ViewModelStore实例并保存在ActivityClientRecord中的
Activity重建后如何恢复ViewModelStore
1,当handleDestroyActivity执行完毕就已经把ViewModelStore的实例获取到并存放到ActivityClientRecord中,此时就开始执行handleLaunchActivity()方法来启动activity
2,handleLaunchActivity()这个方法也需要ActivityClientRecord这个参数,而此时ActivityClientRecord这个对象正是经过handleDestroyActivity()这个方法获取并保存了ViewModelStore 实例的对象
3,handleLaunchActivity()则调用了performLaunchActivity()方法来启动Activity
4,通过代码发现performLaunchActivity调用了当前正在打开的Activity的attach方法,而这个方法需要一个NonConfigurationInstances类型的参数,这个参数里面就有我们的ViewModelStore实例
5,在attach方法里就把这个参数赋值给mLastNonConfigurationInstances,当我们获取ViewModelStore实例的时候,就会先去mLastNonConfigurationInstances中取,如果没有再自己创建一个ViewModelStore实例,到这里整个调用链就搞明白了
生命周期绑定
总结
1,ComponentActivity实现了ViewModelStoreOwner接口并实现了其抽象方法getViewModelStore()
2,我们通过ViewModelProvider使用默认工厂创建了ViewModel,通过唯一key值进行标识并保存到ViewModelStore中
3,当切换横竖屏的时候ActivityThread接收到RELAUNCH_ACTIVITY消息,就会调用Activity的retainNonConfigurationInstances()方法获取我们的ViewModelStore实例并保存起来
4,当Activity启动并调用attach()方法时就将切换横竖屏前的ViewModel恢复过来
5,当我们获取ViewModelStore实例的时候会调用先getLastNonConfigurationInstance()方法去取ViewModelStore,如果为null就会重新创建ViewModelStore并存储在全局中
6,当生命周期发生改变,并且状态为ON_DESTROY,清除ViewModel数据以及实例
到此这篇关于Android Jetpack库剖析之ViewModel组件篇的文章就介绍到这了,更多相关Android ViewModel内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!