| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Android mvvm框架之ViewModel篇 -> 正文阅读 |
|
[移动开发]Android mvvm框架之ViewModel篇 |
目录
1 什么是 ViewModel[Top]1.1 先考虑两个场景
1.2 缺点随着业务规模的扩大,以上的两种场景在传统实现方法中显得越来越繁琐且不易维护,且数据模块不易独立进行测试。 1.3 特别说明关于场景一,同样的场景还适用于各种配置相关的信息发生变化的情况,比如键盘、系统字体、语言区域等,它们的共同作用是都会导致当前 Controller 的重建。 1.4 ViewModel 解决的问题ViewModel 是 android 新的 mvvm 框架的一部分,它的出现就是为了解决以上两个场景中数据与 Controller 耦合过度的问题。其 基本原理 是:维护一个与配置无关的对象,该对象可存储 Controller 中需要的任何数据,其生命周期与宿主 Controller 的生命周期保持一致,不因 Controller 的重建而失效(注意:Controller 的重建仍然在 Controller 生命周期内,并不会产生一个新的生命周期,即 Controller 的 onDestroy 并不会调用) 这意味着无论是转屏还是系统字体变化等因配置变化产生的 Controller 重建都不会回收 ViewModel 中维护的数据,重建的 Controller 仍然可以从同一个 ViewModel 中通过获取数据恢复状态。 2 ViewModel 实现原理[Top]2.1 ViewModel 类如果大家去看一下 ViewModel 类的实现,会发现虽然它是一个 abstract 类,但是没有暴露任何外部可访问的方法,其预留的方法都是 package 访问权限的, 2.2 ViewModel 的构造过程我们用一个结构图来剖析 ViewModel 的构造过程: 如图所示:
本小节剩下部分分析源码,对于只关心原理的同学此部分可以略过: 我们在获取 ViewModel 的时候,一般通过如下方式:
我们看一下 ViewModelProviders.of() 的实现:
我们再看一下 ViewModelProvider.get() 方法获取 ViewModel 实例的过程:
3 ViewModel 与配置无关的原理(与宿主 Controller 俱生俱灭)[Top]上一节我们说到,ViewModel 之所以能够与宿主 Controller 保持生命周期一致,是因为存储它的 ViewModelStore 与宿主 Controller 生命周期一致。那么为什么 ViewModelStore 能够保持和 Controller 生命周期一致呢? 这里我们需要先理清 FragmentActivity 和其寄生的 Fragment 的 ViewModelStore 之间的关系: 3.1 ViewModelStore 树如图所示:
所以,我们看到,处于顶层的 FragmentActivity 的 ViewModelStore 是一个超级 Store,它引用了所有的 ViewModels,包括自身的数据、所有子孙 Fragment 的 ViewModels,只要各子孙 Fragment 不清除自有 ViewModelStore,则所有的数据都维护在这棵 ViewModelStore 树中。 那么在配置发生变化的时候,ViewModelStore 树如何保持不变呢? 3.2 系统级的配置无关支持将 ViewModelStore 作为配置无关数据进行保持,在 FragmentActivity 中是这么做的: 是的,流程就是这么简单,只需要将 ViewModelStore 封装在一个特殊对象中保存并在 FragmentActivity 的 onRetainNonConfigurationInstance() 方法中返回即可:
这样,在顶层源头上就保证了所有 Controller 的 ViewModels 不会在发送配置变化的时候由于 Controller 重建而被销毁。 另外在 Fragment 层中,必须区分 Fragment 实例销毁时到底是因为调用了 onDestroy 还是配置发生了变化,如果是前者则必须清理自身持有的 ViewModelStore,如果是后者则不能清理: 如图所示,也说明了 Fragment 的 ViewModel 生命周期与该 Fragment 生命周期是一致的。
4 FragmentActivity 中的 ViewModel 生命周期[Top]最后,我们还需要说明一下,FragmentActivity 中的 ViewModel 的生命周期是如何保持与 FragmentActivity 一致的,除了上一节中 FragmentActivity.onRetainNonConfigurationInstance() 中的配置无关保证以外,还需要保证在 Activity 真正销毁的时候其所持有的 ViewModel 也应该被清理。 其代码实现非常简单,只需要观察该 Activity 的 Lifecycle 状态,并在销毁状态时进行清理即可,关于 Lifecycle 我们将用专门的章节进行说明,以下为清理代码:
5 多 Controller 共享 ViewModel[Top]我们参考第3.1节的 ViewModelStore 树可知,如果多个 Controller 需要共享同一个 ViewModel 的话,我们只需要将该 ViewModel 保存在这些 Controller 共同的父 Controller 的 ViewModelStore 中即可,而这些子 Controller 可以通过如下方式获取这个共享的 ViewModel:
这样我们就解决了在 1.1 节中提到的第二个场景共享数据的问题。 6 关于工厂模式的一点思考[Top]回到第2节中如何获取一个 ViewModel 实例的过程,我们发现,ViewModelProviders 实际相当于一个 简单工厂 模式,而 Facotry 则是一个 工厂方法 模式,前者根据不同的参数构造不同的 ViewModelProvider,后者则可以实现不同的具体 Factory 来构造不同的 ViewModel。 这里有两层抽象:
所以我们看到,当一个对象的构造是采用了统一的规则时(比如 ViewModelProvider),适合用简单工厂模式来实现,因为该规则本身可以被封装;而当一个对象的构造方式没有统一规则可以遵循,其实现细节更多与业务相关时,其可被封装的部分仅为它的 new 方法,这时更适合用工厂方法模式来实现。
如果大家喜欢我写的文章,欢迎扫码关注小舍的公众号,将有更多有趣的内容分享给大家: |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/28 11:59:41- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |