ViewModel原理解析,人人都能看得懂!

 我来答
温屿17
2022-06-05 · TA获得超过1.2万个赞
知道小有建树答主
回答量:827
采纳率:0%
帮助的人:93.5万
展开全部
今天想跟大家聊的是 Jetpack 组件之 ViewModel , 之前对 ViewModel 也是一知半解,只是从博客上大概了解过它的原理,自己并没有深入了解过,所以打算自己由浅入深的领略一下,本人自己感觉不算是聪明的那类人,连我都能看得懂,相信各位肯定没问题,人人都能看得懂!

先来看看 ViewModel 是什么?

这两个介绍摘自于官网文档,其中说明ViewModel的作用,主要是保存UI数据的。我们来看看它的生命周期:

可以看到 ViewModel 在UI整个生命周期范围内都是同一个状态内的,当UI销毁的时候才会执行 onCleard() 操作,清除数据。

接下来,我们看下 ViewModel 的简单使用

首先我们创建一个 ViewModel

然后在UI中进行获取到 MainViewModel ,并进行数据订阅

先实例化 ViewModelProvider ,通过 ViewModelProvider::get 方法来获取 MainViewModel 的实例对象,通过这种创建形式,不难看出, ViewModel 的创建是通过反射来创建的。

那么 ViewModle 是如何保存数据的呢?今天就由浅入深的带大家来领略一下 ViewModel 的奥妙之处,保证人人都能看得懂!

首先我们从 ViewModelProvider 看起,先了解一下它的面目。

在这里,这个构造方法 新建了一个默认的工厂,然后调用了自己默认的构造方法。其中这个工厂就是用来创建 ViewModel 的。

接下来看看get方法做了点什么?

这里就是增加了一个默认的 Key 值,然后调用另外一个 get 方法,这个默认 Key 是

在这个方法中,可以看到,根据 key 值从 store 中获取 ViewModel 对象,如果 类型正确 ,当即返回当前对象, 如果不正确的话,通过工厂创建新的 ViewModel 对象,存储到 store 中并返回。

我们先看看工厂是如何创建 VIewModel 的

这是前面 ViewModelProvider 创建的默认工厂,最后通过 modelClass.newInstance() 创建了 ViewModel 的实例化对象。

接下来我们看看看 store 是什么?

store 的类型是 ViewModelStore

可以看到它里面维护了一个 HashMap ,根据 Key 值 来对 ViewModel 进行存储。同时提供了 clear() 方法,将所有 ViewModel 清除。

这个 ViewModelStore 是在什么时候创建的呢?

在上文提到的创建 ViewModelProvider 的时候,可以看到, ViewModelStoreOwner 是由 Activity 创建 ViewModelProvider 的时候 传入的,然后调用 owner 中的 getViewModelStore() 方法,获取 ViewModelStore ,并传到构造方法里面的。

这是因为 AppCompatActivity 的父类 ComponentActivity 实现了 ViewModelStoreOwner 接口。

ViewModelStoreOwner 接口就很简单,只提供了一个 getViewModelStore() 方法 来获取 ViewModelStore ,我们来看看它的实现。

这里面只是简单返回了 mViewModelStore 对象 ,重要的是 ensureViewModelStore() 方法。

这里主要是获取 NonConfigurationInstances 对象,然后从中获取到 viewModelStore ,如果 NonConfigurationInstances 为空的话,就新建一个 ViewModelStore 对象。

接下来我们主要看下 getLastNonConfigurationInstance(); 方法。

我将这个方法的注释做了翻译:

简单来说,这个方法就是用来获取 onRetainNonConfigurationInstance () 方法中存储的内容。

这样对比来看不难看出:

onRetainNonConfigurationInstance() 是在 Activity 销毁的时候 进行存储信息。

getLastNonConfigurationInstance() 的作用是获取 存储的信息的。

当屏幕发生旋转的时候 ,会先调用 onRetainNonConfigurationInstance 先将数据进行保存,然后再通过 getLastNonConfigurationInstance 将保存的数据获取到。

我们来看看 ComponentActivity 对 onRetainNonConfigurationInstance 的实现:

mViewModelStore 是在 ensureViewModelStore 方法中获取的对象( 可能是通过 getLastNonConfigurationInstance() 获取,可能是重新创建 ) ,如果这个 mViewModelStore 是空的话,就会尝试从 NonConfigurationInstances 中获取,如果仍然是空,直接返回 null ,如果不是空的话, 重新创建 nci 进行存储。

那这些数据什么时候才会清除呢?

在 ComponentActivity 的无参构造中,对生命周期做了一个监听,当页面进行销毁的时候,并且没有配置更改的时候,会执行

mViewModelStore 的 clear() 方法,进行数据的释放操作。

整个流程,大概就是这样

分析了这么多,我们捋一下:

onRetainNonConfigurationInstance() 方法将 viewModelStore 保存起来,然后再调用 getLastNonConfigurationInstance 方法将数据恢复,如果为空的话,会重新创建 viewModelStore ,并存储在全局中,以便以下次发生变化的时候,能够通过 onRetainNonConfigurationInstance 保存起来。

今天就聊这么多,希望本文能够对内卷路上的你有所帮助。前段时间听到一句话,“种一棵树,最好的时间就是十年前和现在”,与君共勉。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
威孚半导体技术
2024-08-19 广告
威孚(苏州)半导体技术有限公司是一家专注生产、研发、销售晶圆传输设备整机模块(EFEM/SORTER)及核心零部件的高科技半导体公司。公司核心团队均拥有多年半导体行业从业经验,其中技术团队成员博士、硕士学历占比80%以上,依托丰富的软件底层... 点击进入详情页
本回答由威孚半导体技术提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式