其他相关文章:

  1. ViewModel 在 Activity 中的实现原理

1. 前言

ViewModel 的作用是专门存放与界面相关的数据,分担 Activity/Fragment 的逻辑,同时会维护自己独立的生命周期。如当系统配置发生变更(如切换语言等)、横竖屏切换等,可能会导致 Activity 销毁重建,假设要被销毁是 Activity A,需要被重新创建的是 Activity B,虽然他们都属于同一类型,但是是两个不同的实例对象。因此在 Activity 销毁重建的过程中,就涉及 A 在销毁时,其内部维护的数据要过渡到重建的 B 中,这就依赖于 ViewModel。

ViewModel is a class that is responsible for preparing and managing the data for an Activity or a Fragment. It also handles the communication of the Activity / Fragment with the rest of the application (e.g. calling the business logic classes).
.
A ViewModel is always created in association with a scope (an fragment or an activity) and will be retained as long as the scope is alive. E.g. if it is an Activity, until it is finished.
.
In other words, this means that a ViewModel will not be destroyed if its owner is destroyed for a configuration change (e.g. rotation). The new instance of the owner will just re-connected to the existing ViewModel.
.
引用自 https://developer.android.com/reference/android/arch/lifecycle/ViewModel

ViewModel 一般在 MVVM 模式中协同 Jetpack 的其他组件一起使用。另外,ViewModel 的使用需要引入:androidx.lifecycle:lifecycle-viewmodel (本文涉及的版本为 2.2.0)。

2. ViewModel 常用的创建方式

由于 ViewModel 的生命周期是由系统维护的,因此不能直接在代码中通过 new 的方式创建。

另外 androidx.lifecycle.ViewModelProviders 在高版本中已经被废弃。

(1)直接基于 ViewModelProvider 获取

ViewModelProvider(activity/fragment).get(XXXViewModel::class.java)

(2)通过 ViewModelFactory 创建

class TestViewModelFactory(private val param: Int) : ViewModelProvider.Factory {override fun <T : ViewModel> create(modelClass: Class<T>): T {return TestViewModel(param) as T}}// 实例代码
ViewModelProvider(activity/fragment, TestViewModelFactory(0)).get(TestViewModel::class.java)

其实,上述两种方式最终都是基于 ViewModelProvider.Factory 来生成 ViewModel 实例,只不过第一种方式如果不传 Factory,内部会使用默认的 Factory

另外:

  • 当需要在 androidx.fragment.app.Fragment 中获取 ViewModel 实例时,可以基于 androidx.fragment:fragment-ktxFragmentViewModelLazyKt 的扩展方法来实现懒加载。具体可以参考 Google architecture-samples TaskDetailFragment 的实现。
  • 当需要在 androidx.activity.ComponentActivity 中获取 ViewModel 实例时,可以基于 androidx.activity:activity-ktxActivityViewModelLazyKt 的扩展方法来实现懒加载。
@MainThread
inline fun <reified VM : ViewModel> ComponentActivity.viewModels(noinline factoryProducer: (() -> Factory)? = null
): Lazy<VM> {val factoryPromise = factoryProducer ?: {defaultViewModelProviderFactory}return ViewModelLazy(VM::class, { viewModelStore }, factoryPromise)
}

3. ViewModel 的生命周期

ViewModel 目前只有一个生命周期方法 onCleared(),是在 ViewModel 实例对象被清除的时候回调。

4. 关于 ViewModel 的架构规范

在 Google 的 architecture-samples(main 分支)Demo 中,在创建 ViewModel 实例时,会传递以 Repository 为后缀的接口实现实例。这其实是实现 MVVM 模式时的一种规范。

Repository 为后缀的接口,用于连接数据层,定义数据操作的约束与规范,然后由具体的实现类去实现(如去数据库加载数据、从网络获取数据)。从而 ViewModel 与数据层的操作逻辑解耦,只需要关注业务逻辑。参考:TasksRepository。


ViewModel 简析相关推荐

  1. Android Jetpack组件App Startup简析

    1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面. A ...

  2. 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析

    目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...

  3. 简析平衡树(三)——浅谈Splay

    前言 原本以为\(Treap\)已经很难了,学习了\(Splay\),我才知道,没有最难,只有更难.(强烈建议先去学一学\(Treap\)再来看这篇博客) 简介 \(Splay\)是平衡树中的一种,除 ...

  4. 基于libmad库的MP3解码简析

    基于libmad库的MP3解码简析  MAD (libmad)是一个开源的高精度 MPEG 音频解码库,支持 MPEG-1(Layer I, Layer II 和 LayerIII(也就是 MP3). ...

  5. 简析 .NET Core 构成体系

    简析 .NET Core 构成体系 Roslyn 编译器 RyuJIT 编译器 CoreCLR & CoreRT CoreFX(.NET Core Libraries) .NET Core 代 ...

  6. Python源码学习:内建类型简析并简析int对象

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> 上一篇文章中已经大致分析了下,Python的启动执行流程,现在我们分析一下Pytho ...

  7. Python源码学习:启动流程简析

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> Python简介: python主要是动态语言,虽然Python语言也有编译,生成中 ...

  8. 简析TCP的三次握手与四次分手【转】

    转自 简析TCP的三次握手与四次分手 | 果冻想 http://www.jellythink.com/archives/705 TCP是什么? 具体的关于TCP是什么,我不打算详细的说了:当你看到这篇 ...

  9. ceph存储原理_Ceph存储引擎BlueStore简析

    前文我们创建了一个单节点的Ceph集群,并且创建了2个基于BlueStore的OSD.同时,为了便于学习,这两个OSD分别基于不同的布局,也就是一个OSD是基于3中不同的存储介质(这里是模拟的,并非真 ...

最新文章

  1. Vue.js 数据绑定渲染Demo
  2. 《LeetCode力扣练习》第3题 C语言版 (做出来就行,别问我效率。。。。)
  3. Go []byte to a C *char
  4. 关于JAVA项目中CLASSPATH路径详解
  5. 模块--random
  6. WinLaucher启动
  7. [蓝桥杯2018初赛]第几天-日期计算(水题)
  8. android 将bitmap存为 bmp格式图片大小,把bitmap保存成 BMP的格式 并且位深度为1
  9. 牛津教授吐槽DeepMind心智神经网络,还推荐了这些多智能体学习论文
  10. dfs深度优先搜索_图的深度优先搜索(DFS)
  11. Silverlight 2中多语言支持实现(下)
  12. 20141110的alltosun面试
  13. lwip协议栈实现服务器端主动发送,lwip协议栈源码详解说明 - 全文
  14. Linux系统下安装ssh服务
  15. android 适配俄语添加,【技术贴】怎么在手机上添加俄语输入法?,怎样在电脑上打俄语重音?...
  16. 苹果8android价格,iphone8plus相当于什么档次的安卓机?从这3方面就可看出
  17. Python 计算两个连通子图距离_复杂网络分析之python利器NetworkX
  18. fetch bulk collect limt 学习
  19. tomcat的环境变量的配置
  20. 专业创造奇迹 彩票行业进入数据分析时代

热门文章

  1. python endswith函数_Python中endswith()函数的使用方法
  2. Linux重启网卡失败解决办法
  3. 宁夏职业计算机学校有哪些,宁夏十大中职学校一览表
  4. 仓储业务外包可以帮助企业解决哪些问题?
  5. 电商控价,为什么要找控价公司
  6. Python机器学习基础教程——鸢尾花分类
  7. 北宋唐慎微编撰《经史证类备急本草》
  8. TransparentBlt
  9. 从淘宝到天猫,东南亚电商Lazadashopee卖家务必早早开始布局品牌
  10. 软件测试之BUG处理流程