ViewModel 和 ViewModelProvider.Factory:ViewModel 的创建者

朋友们好,今天我向大家介绍下 ViewModel 中如何使用 ViewModelProvider.Factory.
现在开始
所以,我们首要问题是:什么是 ViewModelProvider.Factory ?让我们在不使用 ViewModelProvider.Factory 的情况下,试着创建一个 ViewModel 看看:

在活动中实例化:

有没有人注意到:当我们使用 ViewModelProviders 在活动中实例化 MyViewModel 时,从未没用过 MyViewModel 的构造方法,而都是使用 ViewModelProviders 这个类中的方法。ViewModelProviders 在内部为我们管理并调用 ViewModel 的主构造函数,创建viewmodel的实例并将该实例并返回。
那么,现在让我们看看,如果我们直接把参数传递给 MyViewModel 类的构造方法时会发生了什么:

现在,我们在活动中创建 MyViewModel 实例:

太棒了!没有发生任何错误
但是,等等。
当你运行上面这段代码的时候,你收到了 RunTimeError。程序崩溃了!!! RuntimeException 不能创建出 MyViewModel 实例。
现在我们为什么会发生这些。ViewModelProviders 的 of() 方法,在内部创建了默认的 ViewModelProvider.Factory ,从而实现了 ViewModel 的无参创建。所以,当我们在构造方法添加参数时, ViewModelProvider.Factory 的内部无法实例化 ViewModel 对象,因为 ViewModelProvider.Factory 调用主构造方法创建 ViewModel’s 实例而失败。下图是 ViewModelFactory ViewModelFactory 的默认实现。

如果你想在构造方法中添加参数,你需要编写自己的 ViewModelProvider 来创建 ViewModel 实例。
什么是 ViewModelProvider.Factory?
ViewModelProviders.Factory 接口是负责实例化 ViewModels 对象的启动装置。这意味着你需要自己写实例化 ViewModel 对象的方法。
让我们像下面这样创建自己的 ViewModelProvider.Factory :

这里有几点需要记下:
- 你需要通过构造方法或者其他你喜欢的途径(比如 Singleton, FactoryPattern 等等)。这是由于你在实例化 ViewModel 对象时,不能直接在活动或者碎片中调用 ViewModel 的构造方法,而且你又想去设置 ViewModel 构造方法的参数,因此你需要将参数传入 ViewModelProvider.Factory 它将会帮你创建你的 ViewModel。
- ViewModelProvider.Factory 是一个包含 create 方法的接口。这个 create 方法负责创建你的 VeiwModel’s 实例。
- modelClass.getConstructor(Int::class.java) 方法是一个整型的能够通过调用 newInstance 方法来想构造方法传值的方法。
现在就让我们通过 ViewModelProvider.Factory 在活动中创建 ViewModel 实例。

我们将参数或者依赖关系转入我们的 ViewModelProvider.Factory 以便于它能够为我们创建 ViewModel,ViewModelProviders.of( context, instanceOfViewModelFactory) 方法获得我们 ViewModelProvider.Factory 实例,现在就像之前的例子中一样,我们已经学会了创建 ViewModel 实例的过程。
所以,为什么我们需要 ViewModelProvider.Factory ?
我们心中有这样一些疑问,我们不能直接在活动或碎片中将值传入 ViewModel 构造方法中去,我需要写法来设置我们的参数值使其正常工作,这就是为什么我们需要 ViewModelProver.Factory,在一些情况下你可以不使用,但在某些特定情形下,你需要使用 ViewModelProver.Factory。
什么时候使用 ViewModelProvider.Factory
当你的 ViewModel 有依赖项,并且你需要将这些依赖项通过构造方法传入,因此,您可以模拟该依赖项并测试 ViewModel。
什么时候不应该使用 ViewModelProvider.Factory
如果你的 ViewModel 没有依赖项,这时你就不需要去自己创建 ViewModelProvider.Factory。系统自带的方法,注意帮助你创建 ViewModel。
总结
ViewModelProvider.Factory 负责帮你创建 ViewModel 实例。当你的 ViewModel 存在依赖项,且你希望测试你的 ViewModel 时,你需要创建自己的 ViewModelProvider.Factory 来通过 ViewModel 的构造方法传递依赖项,将你的数值传入 ViewModelProvider.Factory 实例中去
你的关注是我最大的动力!
ViewModel 和 ViewModelProvider.Factory:ViewModel 的创建者的更多相关文章
- Android 让你的 Room 搭上 RxJava 的顺风车 从重复的代码中解脱出来
# 什么是 Room ? 谷歌为了帮助开发者解决 Android 架构设计问题,在 Google I/O 2017 发布一套帮助开发者解决 Android 架构设计的方案:Android Archit ...
- 每个人都要学的图片压缩终极奥义,有效解决 Android 程序 OOM
# 由来 在我们编写 Android 程序的时候,几乎永远逃避不了图片压缩的难题.除了应用图标之外,我们所要显示的图片基本上只有两个来源: 来自网络下载 本地相册中加载 不管是网上下载下来的也好,还是 ...
- Android笔记之ViewModel的使用示例
依赖 implementation 'android.arch.lifecycle:extensions:1.1.1' implementation 'com.squareup.retrofit2:r ...
- Android Jetpack组件 - ViewModel,LiveData使用以及原理
本文涉及的源码版本如下: com.android.support:appcompat-v7:27.1.1 android.arch.lifecycle:extensions:1.1.1 android ...
- Android架构组件——ViewModel
概述 ViewModel,从字面上理解的话,它肯定是跟视图(View)以及数据(Model)相关的.正像它字面意思一样,它是负责准备和管理和UI组件(Fragment/Activity)相关的数据类, ...
- Jetpack架构组件学习(2)——ViewModel和Livedata使用
要看本系列其他文章,可访问此链接Jetpack架构学习 | Stars-One的杂货小窝 原文地址:Jetpack架构组件学习(2)--ViewModel和Livedata使用 | Stars-One ...
- ViewModel的创建
ViewModel的创建 ViewModel本身只是ViewModel这个类的子类: class MainViewModel: ViewModel() { } 在屏幕旋转UI重建的时候, 它是如何拥有 ...
- 改造 Android 官方架构组件 ViewModel
前言 Android 官方架构组件在今年 5 月份 Google I/O 大会上被公布, 直到 11 月份一直都是测试版, 由于工作比较繁忙, 期间我只是看过类似的文章, 但没有在实际项目中使用过, ...
- Jetpack 架构组件 LiveData ViewModel MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
随机推荐
- [Python] 通过采集23万条数据,对《哪吒》影评分析
一.说明 数据来源:猫眼: 运行环境:Win10/Python3.7 和 Win7/Python3.5: 分析工具:jieba.WorldCloud.pyecharts和matplotlib: 程序基 ...
- Mac os 下 python爬虫相关的库和软件的安装
由于最近正在放暑假,所以就自己开始学习python中有关爬虫的技术,因为发现其中需要安装许多库与软件所以就在这里记录一下以避免大家在安装时遇到一些不必要的坑. 一. 相关软件的安装: 1. h ...
- TextCNN 代码详解(附测试数据集以及GitHub 地址)
前言:本篇是TextCNN系列的第三篇,分享TextCNN的优化经验 前两篇可见: 文本分类算法TextCNN原理详解(一) 一.textCNN 整体框架 1. 模型架构 图一:textCNN 模型结 ...
- Java NIO系列之[说在前面的话]
在开始这个系列文章之前,先聊一些题外话,说说我为什么要写Java NIO这个系列技术文章(不看完会错失一个亿的),因为Java NIO并不像JVM,中间件源码那么有吸引力,但这个技术点是java的基础 ...
- CFdiv2 165E. Compatible Numbers 子集枚举
传送门 题意: 给出一个序列,输出每个数x对应的一个ans,要求ans在数列中,并且ans & x = 0:数列的每个数小于(4e6) 思路: 这道题的方向比较难想.想到了就比较轻松了,可以 ...
- bzoj 4025 二分图 lct
题目传送门 题解: 首先关于二分图的性质, 就是没有奇环边. 题目其实就是让你判断每个时段之内有没有奇环. 其次 lct 只能维护树,(反正对于我这种菜鸟选手只会维护树), 那么对于一棵树来说, 填上 ...
- 【Hystrix】实现服务隔离和降级
一.背景 1.1 服务熔断 1.2 服务降级 1.3 服务隔离 1.4 总结 二.使用Hystrix实现服务隔离和降级 2.1 Hytrix 简介 2.2 线程池方式 2.3 信号量 三.项目搭建 3 ...
- 【Redis】基础学习概览【汇总】
一.概述 1.1 简介 1.2 Redis单线程好处 1.3 单线程弊端 1.4 Redis应用场景 二.安装.开启以及关闭 三.Redis基本数据类型 四.SpringBoot整合Redis 五.R ...
- 如何在 Ubuntu 上安装 MongoDB
MongoDB 是一个越来越流行的自由开源的 NoSQL 数据库,它将数据存储在类似 JSON 的灵活文档集中,这与 SQL 数据库中常见的表格形式形成对比. 你很可能发现在现代 Web 应用中使用 ...
- c语言实现数组的排序
本文章只对选择排序和冒泡排序进行介绍 选择排序实际上是从0到length-1,选择某个元素与其他的元素进行大小比较,如果大于就交换,其他情况不做操作,如图: 冒泡排序实际上是先选择某个元素,然后从 ...