Jetpack Architecture系列教程之(三)——ViewModel控制器

目录

介绍

如何使用

添加依赖

构建ViewModel

分析ViewModel

ViewModel生命周期

ViewModel加载原理


介绍

         ViewModel 的出现是为了解决数据因Android UI控制器在生命周期活动中造成数据丢失的问题。

        在一般情况下,页面数据丢失(转屏、闪退等生命周期重建现象)我们都会通过onSaveInstanceState() 方法并从 onCreate() 中的包中恢复其数据。但此方法仅适用于可以序列化然后反序列化的少量数据,而不适用于潜在的大量数据像用户列表或位图。 另一个问题是UI控制器经常需要进行可能需要一些时间才能返回的异步调用。UI控制器需要管理这些调用并确保系统在销毁后清理它们以避免潜在的内存泄漏。此管理需要大量维护,并且在为配置更改重新创建对象的情况下,这会浪费资源,因为对象可能必须重新发出已经进行的调用。

        诸如活动和片段之类的UI控制器主要用于显示UI数据,对用户操作作出反应或处理操作系统通信,例如许可请求。要求UI控制器也负责从数据库或网络加载数据,这会给类增加膨胀。为UI控制器分配过多的责任可能导致单个类尝试自己处理应用程序的所有工作,而不是将工作委托给其他类。以这种方式为UI控制器分配过多的责任也会使测试变得更加困难。 而 ViewModel 将视图数据所有权与UI控制器逻辑分离起来更容易,更有效的解决这一系列问题。

如何使用

添加依赖
// lifecycle
def lifecycle_version = "2.2.0-alpha02"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"
kapt "android.arch.lifecycle:compiler:$lifecycle_version"
构建ViewModel
class BaseModel: ViewModel() {var userTag = ""}
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val tvContent = findViewById<TextView>(R.id.tv_content)val baseModel = ViewModelProviders.of(this)[BaseModel::class.java]if(baseModel.userTag.isNotEmpty()){tvContent.text = baseModel.userTag}tvContent.setOnClickListener {baseModel.userTag = "Hello BaseModel"tvContent.text = baseModel.userTag}}}

分析ViewModel

ViewModel生命周期

        获取ViewModel时,ViewModel对象的范围限定为传递给ViewModelProvider的生命周期。 ViewModel保留在内存中,直到它的作用域生命周期永久消失:在活动的情况下,当它完成时,在片段的情况下,当它被分离时。 图中显示了活动经历轮换然后结束时的各种生命周期状态。该图还显示了关联活动生命周期旁边的ViewModel的生命周期。 此特定图表说明了活动的状态。相同的基本状态适用于片段的生命周期。

        通常在系统第一次调用活动对象的onCreate()方法时请求ViewModel。 系统可以在活动的整个生命周期中多次调用onCreate(),例如在旋转设备屏幕时。 而ViewModel从第一次请求ViewModel到活动完成并销毁之时就存在。

ViewModel加载原理

        ViewModel将UI控制器与数据加载操作分开,这意味着类之间的强引用较少,ViewModel内部是与Room和LiveData一起使用以达到替换加载的效果。 当数据发生变化时,Room存储层会通知到LiveData,然后LiveData会使用修改后的数据更新UI,这样确保数据在设备配置更改后仍然存在。

        关于LiveData,它是一个数据维持类,底层由Map实现。下篇文章会讲到,这里略知一二即可。

        关于Room,它是一个ORM库。后续文章会讲到,这里略知一二即可。

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

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

相关文章

在低功耗MCU上实现人工智能和机器学习

作者&#xff1a;Silicon Labs 人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;技术不仅正在快速发展&#xff0c;还逐渐被创新性地应用于低功耗的微控制器&#xff08;MCU&#xff09;中&#xff0c;从而实现边缘AI/ML解决方案。这些MCU是许多嵌入式…

rpc到自己java实现rpc调用再到rpc框架设计

目录 rpc(Remote Procedure Call)rpc一般架构为什么要引入rpc自己实现rpc调用1. 新建一个maven项目&#xff0c;加入hessian依赖2. 服务端3. Stub代理4. 客户端测试输出5. rpc程序分析附 请求参数和序列化程序 6. 总结 回顾RPCRPC 序列化协议RPC 网络协议注册中心的引入dubbo框…

【STM32 USB】USB CDC类

简介 USB CDC&#xff08;communication device class&#xff09;类是usb2.0标准下的一个子类&#xff0c;定义了通信相关设备的抽象集合。usb2.0标准下定义了很多子类&#xff0c;有音频类&#xff0c;CDC类&#xff0c;HID类&#xff0c;打印&#xff0c;大容量存储类&…

如何修改Windows系统Ollama模型存储位置

默认情况下&#xff0c;Ollama 模型会存储在 C 盘用户目录下的 .ollama/models 文件夹中&#xff0c;这会占用大量 C 盘空间&#xff0c;增加C盘“爆红”的几率。所以&#xff0c;我们就需要修改Ollama的模型存储位置 Ollama提供了一个环境变量参数可以修改Ollama的默认存在位…

DeepSeek掘金——VSCode 接入DeepSeek V3大模型,附使用说明

VSCode 接入DeepSeek V3大模型,附使用说明 由于近期 DeepSeek 使用人数激增,服务器压力较大,官网已 暂停充值入口 ,且接口响应也开始不稳定,建议使用第三方部署的 DeepSeek,如 硅基流动 或者使用其他模型/插件,如 豆包免费AI插件 MarsCode、阿里免费AI插件 TONGYI Lin…

【语音科学计算器】当前汇率

JSON_MARKER_HORN{“base”:“USD”,“rates”:{“EUR”:0.9758,“JPY”:157.68,“GBP”:0.8190,“CNY”:7.3327,“HKD”:7.7872,“AUD”:1.6260,“CAD”:1.4422,“CHF”:0.9157,“SGD”:1.3714,“KRW”:1473.05,“NZD”:1.7992,“THB”:34.54,“MYR”:4.4930,“PHP”:57.32,“…

Codes 开源免费研发项目管理平台 2025年第一个大版本3.0.0 版本发布及创新的轻IPD实现

Codes 简介 Codes 是国内首款重新定义 SaaS 模式的开源项目管理平台&#xff0c;支持云端认证、本地部署、全部功能开放&#xff0c;并且对 30 人以下团队免费。它通过创新的方式简化研发协同工作&#xff0c;使敏捷开发更易于实施。并提供低成本的敏捷开发解决方案&#xff0…

uniapp 网络请求封装(uni.request 与 uView-Plus)

一、背景 在开发项目中&#xff0c;需要经常与后端服务器进行交互&#xff1b;为了提高开发效率和代码维护性&#xff0c;以及降低重复性代码&#xff0c;便对网络请求进行封装统一管理。 二、创建环境文件 2.1、根目录新建utils文件夹&#xff0c;utils文件夹内新建env.js文…

ESP32-S3 实战指南:BOOT-KEY 按键驱动开发全解析

一、基础知识 本篇我们使用 BOOT 按键来学习一下 GPIO 功能&#xff0c;首先补充一下相关术语介绍。 1、GPIO&#xff08;General Purpose Input/Output&#xff09; GPIO 是微控制器上的通用引脚&#xff0c;既可以作为输入&#xff08;读取外部信号&#xff09;&#xff0…

初学者如何设置以及使用富文本编辑器[eclipse版]

手把手教你设置富文本编辑器 参考来源&#xff1a;UEditor Docs 初学者按我的步骤来就可以啦 一、设置ueditor编辑器 1.提取文件[文章最底部有链接提取方式] 2.解压文件并放到自己项目中&#xff0c;在WebContent目录下&#xff1a; 3. 修改jar包位置路径 到--> 注意&a…

25轻化工程研究生复试面试问题汇总 轻化工程专业知识问题很全! 轻化工程复试全流程攻略 轻化工程考研复试真题汇总

轻化工程复试心里没谱&#xff1f;学姐带你玩转面试准备&#xff01; 是不是总觉得老师会问些刁钻问题&#xff1f;别焦虑&#xff01;其实轻化工程复试套路就那些&#xff0c;看完这篇攻略直接掌握复试通关密码&#xff01;文中有重点面试题可直接背~ 目录 一、这些行为赶紧避…

企业数据集成:实现高效调拨出库自动化

调拨出库对接调出单-v&#xff1a;旺店通企业奇门数据集成到用友BIP 在企业信息化管理中&#xff0c;数据的高效流转和准确对接是实现业务流程自动化的关键。本文将分享一个实际案例&#xff0c;展示如何通过轻易云数据集成平台&#xff0c;将旺店通企业奇门的数据无缝集成到用…

Java高级开发所具知识技能

以下是Java高级开发整理的知识技能,其中涵盖核心技术、框架、分布式架构、性能优化等关键领域: 一、Java核心进阶 JVM深度理解 内存模型(堆、栈、方法区)垃圾回收算法(CMS、G1、ZGC)类加载机制与字节码增强JVM调优工具(jstat、jmap、VisualVM、Arthas)并发编程 线程池(…

【SQL】多表查询案例

&#x1f4e2;本章节主要学习使用SQL多表查询的案例,多表查询基础概念 请点击此处。 &#x1f384;数据准备 首先我们创建一个新的表也就是薪资等级表&#xff0c;其余两个表(员工表和薪资表)在多表查询章节中已经创建。然后我么根据这三个表完成下面的12个需求。 create tab…

PyTorch v2.6 Overview

PyTorch v2.6 Overview Python APILibraries PyTorch 是一个优化的张量库&#xff0c;用于使用 GPU 和 CPU 进行深度学习。 Python API 序号API名称解释1torchPyTorch 核心库(中文:火炬)PyTorch 的核心库&#xff0c;提供了张量操作、自动求导等基础功能。2torch.nn神经网络模…

如何调整CAN位宽容忍度?

CAN位宽容忍度是指在控制器局域网络&#xff08;CAN, Controller Area Network&#xff09;中允许时钟同步的误差范围。这是CAN网络正常通信时的关键因素之一&#xff0c;因为CAN协议依赖位同步来确保多个节点在总线上正确解码数据。CAN位宽容忍度确保节点之间由于时钟偏差或抖…

Django-Vue 学习-VUE

主组件中有多个Vue组件 是指在Vue.js框架中&#xff0c;主组件是一个父组件&#xff0c;它包含了多个子组件&#xff08;Vue组件&#xff09;。这种组件嵌套的方式可以用于构建复杂的前端应用程序&#xff0c;通过拆分功能和视图&#xff0c;使代码更加模块化、可复用和易于维…

怎么学习调试ISP的参数

摄像头的 **Sensor 获取的 RAW 数据** 是未经处理的原始图像数据&#xff0c;通常需要经过 **ISP&#xff08;Image Signal Processor&#xff0c;图像信号处理器&#xff09;** 的处理&#xff0c;才能生成可用的图像或视频。ISP 的作用是对 RAW 数据进行一系列图像处理操作&a…

万字长文解析:深入理解服务端渲染(SSR)架构与全栈实践指南

一、SSR核心原理深度剖析 1.1 技术定义与演进历程 服务端渲染&#xff08;Server-Side Rendering&#xff09;指在服务器端完成页面DOM构建的技术方案。其发展历程可分为三个阶段&#xff1a; 阶段时期典型技术传统SSR2000-2010JSP/PHP现代SSR2015-2020Next.js/Nuxt.js混合渲…

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_array_push

ngx_array_push 声明在 src\core\ngx_array.h void *ngx_array_push(ngx_array_t *a); 实现在 src\core\ngx_array.c void * ngx_array_push(ngx_array_t *a) {void *elt, *new;size_t size;ngx_pool_t *p;if (a->nelts a->nalloc) {/* the array is full…