ViewModel

ViewMode是MVVM架构模式中VM层对应的类,它的作用是存储界面数据,并和界面发生数据交互。ViewModel能感知生命周期,并且在界面由于配置问题发生重建时候,可以保持当前的数据不变。生命周期如下:
在这里插入图片描述

ViewMode由ViewModeProvider创建,然后把创建的ViewModel放入ViewModelStore内部。
MainActivity:

val viewModel : CalendarViewModel by lazy {ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(CalendarViewModel::class.java)}

ViewModelProvider:

public open operator fun <T : ViewModel> get(key: String, modelClass: Class<T>): T {return try {factory.create(modelClass, extras) //创建viewModel} catch (e: AbstractMethodError) {factory.create(modelClass)}.also { store.put(key, it) }  //把ViewModel放入Store的hashmap中}

当配置改变导致的重建时,ViewModelStore不会被重建或者清除,因此ViewModel也不会重建,这主要是因为viewModelStore是被存在ActivityClientRecord中,Activity的销毁不会影响它。
从源代码看看:
Activity被修改配置后(如屏幕旋转)后,导致的销毁重建,会调用onRetainNonConfigurationInstance这个函数,viewModelStore就是在这里恢复的:

  final override fun onRetainNonConfigurationInstance(): Any? {var viewModelStore = _viewModelStoreif (viewModelStore == null) {// ViewModelStore from our last NonConfigurationInstanceval nc = lastNonConfigurationInstance as NonConfigurationInstances?if (nc != null) {viewModelStore = nc.viewModelStore}}}

这里还要获取到上一次的非配置实例lastNonConfigurationInstance,它就是通过ActivityThread中的attach方法,传递给Activity内部的:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {activity.attach(...,r.lastNonConfigurationInstances,...);
}

所以从最后看出,viewModel的数据实际是保存在ActivityClientRecord中的。

ViewModel感知生命周期,是通过Lifecycle去实现的,如下:

lifecycle.addObserver(LifecycleEventObserver { _, event ->if (event == Lifecycle.Event.ON_DESTROY) {     if (!isChangingConfigurations) { //不是配置改变,才会清除viewmodelStoreviewModelStore.clear()}}})

这里也可以看到,当正常的界面销毁(非配置改变导致的销毁)会调用到ViewModelStore的clear方法,清除ViewModel的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/63993.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ESP32-S3模组上跑通ES8388(29)

接前一篇文章:ESP32-S3模组上跑通ES8388(28) 二、利用ESP-ADF操作ES8388 2. 详细解析 上一回解析到了es8388_init函数中的第11段也是最后一段代码,没有解析完,本回继续解析。为了便于理解和回顾,再次贴出该片段,在components\audio_hal\driver\es8388\es8388.c中,如下…

C#—索引器

C#—索引器 索引器&#xff08;Indexer&#xff09;是类中的一个特殊成员&#xff0c;它能够让对象以类似数组的形式来操作&#xff0c;使程序看起来更为直观&#xff0c;更容易编写。索引器与属性类似&#xff0c;在定义索引器时同样会用到 get 和 set 访问器&#xff0c;不同…

智慧城市道路分割数据集labelme格式2648张1类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;2648 标注数量(json文件个数)&#xff1a;2648 标注类别数&#xff1a;1 标注类别名称:["road"] 每个类别标注的框数&#x…

YOLOv5+pyqt5+摄像头在特定条件下进行目标检测并采集原始数据

项目介绍 项目地址 GitHub - biabu0/Yolov5_D435i: 通过YOLOV5与pyqt5实现一个使用D435i深度摄像头采集特定需求与场景下的深度数据的小程序 通过YOLOV5对指定的区域进行检测&#xff0c;当检测到目标进入特定区域时&#xff0c;开始保存数据&#xff0c;摄像头采用D435i深度…

图像的放缩比率如何计算的?

图像的放缩比率如何计算关键点 在医疗软件的胶片打印中&#xff0c;图像放缩比率的计算需要更加精确和考虑更多因素&#xff0c;以确保最终打印出来的影像准确无误&#xff0c;符合诊断要求。 以下是一些关键点&#xff1a; 像素间距&#xff08;Pixel Spacing&#xff09;&a…

leetcode-73.矩阵置零-day5

class Solution {public void setZeroes(int[][] mat) {int m mat.length, n mat[0].length;// 1. 扫描「首行」和「首列」记录「首行」和「首列」是否该被置零boolean r0 false, c0 false;for (int i 0; i < m; i) {if (mat[i][0] 0) {r0 true;break;}}for (int j …

uni-app H5端使用注意事项 【跨端开发系列】

&#x1f517; uniapp 跨端开发系列文章&#xff1a;&#x1f380;&#x1f380;&#x1f380; uni-app 组成和跨端原理 【跨端开发系列】 uni-app 各端差异注意事项 【跨端开发系列】uni-app 离线本地存储方案 【跨端开发系列】uni-app UI库、框架、组件选型指南 【跨端开…

相机不动,机构动作----Hands Eyes

最近在研究 手眼标定&#xff0c;发现大家都需付费&#xff0c;搞啥子&#xff0c;说好的开源。。。 以相机在上固定不动&#xff0c;机械手为 EPSON_Robot 为例&#xff0c;详细的一步一步实例操作指引 EPSON_Robot 的192.168.0.1 2004 Server 详细操作步骤 1. 启动程序 运…

DCDC降压模块

一、项目介绍 在B站看到工科男孙老师发的DCDC模块视频&#xff0c;后面有提到这款芯片&#xff0c;于是就使用这款芯片自己设计了这款降压模块。 芯片的封装为TSOT23-8&#xff0c;对空间利用率高。 输入电压的范围为3-18V。 输出电压的范围为0-8V。 输出电流最…

QILSTE H8-316QFO高亮橙光LED灯珠 发光二极管LED

在当今电子技术领域&#xff0c;H8-316QFO型号的LED以其卓越的性能和可靠性 脱颖而出。本文将深入探讨这款LED的关键参数&#xff0c;以期为工程师和技术人员提供详尽的技术参考。 首先&#xff0c;H8-316QFO的物理特性不容忽视。其外观尺寸为3.2x1.5x0.8mm&#xff0c;小巧的…

康耐视智能相机(Insight)通过ModbusTCP发送字符串到倍福(BECKHOFF)PLC中

文章目录 1.背景2.分析3.实现3.1.PLC的ModbusTCP_Server3.1.1.安装TF6250-Modbus-TCP3.1.2.PLC设置 3.2.智能相机的ModbusTCP_Client3.2.1.了解ModbusTCP的协议3.2.2.根据协议写代码3.2.2.1.纯函数代码3.2.2.2.脚本代码 3.2.3.非脚本处理时的代码逻辑图3.2.4.关于代码的问题及解…

自定义函数库

求两点距离 double dis(double x1, double y1, double x2, double y2){return sqrt(pow(x2-x1, 2)pow(y2-y1, 2)); }判断闰年 bool isLeapYear(int year){return year%40 && year%100!0 || year%4000; }判断素数 bool isPrime(int num){if(num<2) return false;f…

解决前后端发送验证码手机号登陆的sessionId不一致问题

前端&#xff1a;鸿蒙开发ArkTs语言 后端&#xff1a;spring boot mybatis-plus框架 后端代码 PostMapping("/sendMsg")public R<String> sendMsg(RequestBody User user, HttpServletRequest request, HttpServletResponse response) {// 从User对象中提取用…

基于多视角深度学习技术的乳腺X线分类:图神经网络与Transformer架构的研究|文献速递-生成式模型与transformer在医学影像中的应用速递

Title 题目 Mammography classification with multi-view deep learning techniques:Investigating graph and transformer-based architectures 基于多视角深度学习技术的乳腺X线分类&#xff1a;图神经网络与Transformer架构的研究 01 文献速递介绍 乳腺X线检查是乳腺癌…

开发环境服务器 vs 生产环境服务器:开发与生产须分明

【背景】作为开发者&#xff0c;我们在不同的阶段都与两种服务器环境打交道——开发环境服务器和生产环境服务器。虽然听起来名字相似&#xff0c;但它们的职责和工作方式简直是天差地别&#xff01; 不知道朋友们有没有跟我一开始刚了解的时候的一些疑惑&#xff0c;因为刚开始…

Maxscript移动、旋转和缩放

3DMAX对象最常用的三种变换方式是移动、旋转和缩放。本文将详细介绍这些是如何工作的。移动&#xff1a; 使用move函数处理移动&#xff1a; move <object> <vector> 按矢量移动对象&#xff1a; c cone() --c is at 0,0,0 move c [0,1,0] --after this l…

恢复删除的文件:6个免费Windows电脑数据恢复软件

数据恢复软件可帮助您从众多存储设备中恢复损坏或删除的数据。您可以使用这些文件恢复软件来检索文件、文档、视频、图片等。这些应用程序支持多种标准文件格式&#xff0c;如 PNG、RTF、PDF、HTML、JPG、MP3 等。 经过超过 75 小时的研究&#xff0c;我分析了 25 最佳免费数据…

探索 Python 编程调试案例:程序平均值的修复过程

&#x1f49d;&#x1f49d;&#x1f49d;Python 作为一门广泛应用的编程语言&#xff0c;其编程过程并非总是一帆风顺。即使是经验丰富的程序员&#xff0c;也会在代码中遇到各种错误。而调试Python代码过程&#xff0c;也是学习中不可避免的步骤。 今天来看一个简单的案例。…

简单了解一下 Go 语言构建约束?

​构建约束是一种在 Go 语言中控制源文件编译条件的方法&#xff0c;它可以让您指定某些文件只在特定的操作系统、架构、编译器或 Go 版本下编译&#xff0c;而在其他环境中自动忽略。这样可以方便您针对不同的平台或场景编写不同的代码&#xff0c;实现条件编译的功能。 构建…

全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之计数器与累加器实战题目

题目1—三个连续的自然数计算 问题描述&#xff1a; 若有3个连续的自然数&#xff0c;已知第一个自然数为100&#xff0c;请编写程序输出这3个自然数。 输入格式&#xff1a; 无 输出格式&#xff1a; 三行三个整数 输入输出样例&#xff1a; 输入样例 输出样例 无 1…