Android JetPack ViewModel

一、什么是ViewModel?

Android ViewModel在我们使用MVVM开发模式时会经常用到,对我来说就是好用,好维护。

它相对于MVC模式,

一来可以减少Activity层的代码,可以把一些业务逻辑和对数据的交互到ViewModel层去,其次还解决了两个问题:

  • Activity配置更改重建时(比如屏幕旋转)保留数据
  • UI组件(Activity与Fragment、Fragment与Fragment)间实现数据共享。

第一个问题:

在我们某些App的界面,按照业务需求是需要进行屏幕翻转的。所以就会发生activity 重新创建。

当发生配置变更时,系统会重新创建 Activity。为此,系统会调用 onDestroy() 并销毁现有的 Activity 实例。随后,系统会使用 onCreate() 创建一个新实例,并且这个新的 Activity 实例会使用更新后的新配置进行初始化。这也意味着,系统还会使用新配置重新创建界面。
重新创建行为会自动利用与新设备配置相匹配的备用资源来自动重新加载应用,从而帮助它适应新配置。

重新创建过程还会清除您在 Activity 或其包含的 Fragment、View 或其他对象中,以字段形式保留的任何状态。这是因为 Activity 重新创建过程会创建 Activity 和界面的全新实例。此外,之前的旧 Activity 不再可见或不再有效,因此对该 activity 或其所含对象的任何其余引用都已过时。它们会导致 bug、内存泄漏和崩溃。

这时候,不使用VM的情况下只能通过onSaveInstanceState保存数据,当activity重建后再通过onCreateonRestoreInstanceState方法的bundle中取出,但如果数据量较大,数据的序列化和反序列化将产生一定的性能开销。

第二个问题:

不用VM,各个UI组件都要持有共享数据的引用,这会带来两个麻烦,第一,如果新增了共享数据,各个UI组件需要再次声明并初始化新增的共享数据;第二,某个UI组件对共享数据修改,无法直接通知其他UI组件,需手动实现观察者模式。而ViewModel结合LiveData就可以很轻松的实现这一点。

二、ViewModel的使用

1.引入viewmodel(app下的build.gradle)
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
//implementation "android.arch.lifecycle:extensions:1.1.1"

2.创建ViewModel
val viewModel = ViewModelProviders.of(this).get(AndroidViewModel::class.java)
或者
val mainViewModel = ViewModelProvider(this).get(MyViewModel::class.java)

创建流程:

  1. ViewModelStore是存储VM的数据单元,存储结构为Map,Fragment/FragmentActivity持有其引用。(存储数据,在get方法里首先会判断是否已存在该vm)
  2. ViewModelProvider通过get方法创建一个VM,创建之前会先检查ViewModelStore中是否存在,若不存在则通过反射创建一个VM。

三、ViewModel的回收

下面是vm的生命周期官方图,可以看到,它的生命周期算比较长的。当一个activity调用onestroy方法时,正常情况下,会自动走到onClear()方法。

在activity的源码里,可以看到监听到生命周期为销毁时,会去判断是否是更改了配置,如果不是才会去清除

Fragment里稍微深一些:如果因为Activity被嘎调调用Destroy

第一步,看FragementActivity销毁方法://所有的fragment收到销毁的消息

 第二步:FragmentStateManager里(如果fragment的replace方法导致被替换的fragment嘎调也会走到这里来)

viewmodel的生命周期:

4.配置变化的数据保存(其实就是不清除 )

 

VM在Activity因配置变化导致重建时会被保留,从生命周期的角度来说,ViewModel的生命周期可能会长于Activity的生命周期。

所以使用ViewModel时一定要注意,不能让其引用Activity或View,否则可能导致内存泄漏。

四、ViewModel的具体实现

 这儿贴下我在项目中使用ViewModel的代码,因为上面只能说是对他的一个学习。

启屏页面的viewmodel(注意:因为我在这里面引用了activity,可能造成内存泄漏,所以使用了弱引用)

我的splash界面

 使用    private val splashViewModel: AppSplashViewModel by viewModels()声明viewmodel,然后在oncreate下开始倒计时的方法

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Excel模板计算得出表格看板

背景 表格看板及导出,单元格时间年是根据筛选器时间变化的 较往年和往年是计算单元格 思路 1.通过excel模板来把数据填入excel再数据清洗得到数据返回前端 2.数据填充,通过行列作为key 列如:key整体20241月,根据key匹配数据填…

计算机操作系统总结(1)

1操作系统的概念(定义)功能和目标 (1)什么是操作系统? (2)操作系统的功能和目标—作为系统资源的管理者 (3)操作系统的功能和目标—向上层提供方便易用的服务 (4)操作系…

中银基金软件开发工程师春招群面记录

本文介绍2024届春招中,中国银行下属中银基金管理有限公司的软件开发工程师岗位1场面试的基本情况、提问问题等。 2024年04月投递了中国银行的共计4个部门或单位,包括中银基金管理有限公司的软件开发工程师岗位,暂时不清楚所在部门。目前完成了…

平均分配问题

将dwd_phone_shop这六行数据按照1 3 5,2 4 6的排序分为两组,与dwd_phone_base连接,分别与为其中1 3 5 为shop_Id为1的那一组 2 4 6 为shop_Id为2 的那一组 取余法 开窗函数法

南加州大学字节提出MagicPose,提供逼真的人类视频生成,实现生动的运动和面部表情传输,以及不需要任何微调的一致的野外零镜头生成。

MagicPose可以精确地生成外观一致的结果,而原始的文本到图像模型(如Stable Diffusion和ControlNet)很难准确地保持主体身份信息。 此外,MagicPose模块可以被视为原始文本到图像模型的扩展/插件,而无需修改其预训练的权重。 相关链接 论文链…

javaSwing飞机订票系统

摘要 Java swing实现的飞机票预定系统,系统数据库原本采用的是Oracle,我又改了一个mysql版本的,所以这套系统有两个版本,一个是mysql数据库版的,一个是Oracle数据库版 一. 已经完成的功能 : …

Linux基础命令[27]-gpasswd

文章目录 1. gpasswd 命令说明2. gpasswd 命令语法3. gpasswd 命令示例3.1 不加参数3.2 -a(将用户加入组)3.3 -d(从组中删除用户)3.4 -r(删除组密码)3.5 -M(多个用户一起加入组)3.6 …

excel里如何将数据分组转置?

这个表格怎样转换为下表?按照国家来分组,把不同年份对应的不同序列值进行转置?? 这演示用数据透视表就完成这个数据转换。 1.创建数据透视表 选中数据中任意单元格,点击插入选项卡,数据透视表,…

C++设计模式|结构型 适配器模式

1.什么是适配器模式? 可以将⼀个类的接⼝转换成客户希望的另⼀个接⼝,主要⽬的是 充当两个不同接⼝之间的桥梁,使得原本接⼝不兼容的类能够⼀起⼯作。 2. 适配器模式的组成 (1)接口类,给客户端调用&…

vue打包部署到springboot,通过tomcat运行

tomcat默认端口 8080springboot端口 9132vue 端口 9131 框架 项目是基于SpringBootVue前后端分离的仓库管理系统 后端:SpringBoot MybatisPlus前端:Node.js Vue element-ui数据库:mysql 一. 打包Vue项目 cmd中输入命令 npm run build 后…

PHP在线制作表白网源码

PHP在线制作表白网源码,送女友个惊喜吧,无数据库,上传就能用,后台/admin,账号密码都是admin 百度网盘:https://pan.baidu.com/s/1rbD2_8IsP9UPLK-cdgEXfA?pwdre59

前端绘制流程节点数据

根据数据结构和节点的层级、子节点id&#xff0c;前端自己绘制节点位置和关联关系、指向、已完成节点等 <template><div><div>通过后端节点和层级&#xff0c;绘制出节点以及关联关系等</div><div class"container" ref"container&…

本地centos7+docker+ollama+gpu部署

1、一台有 NVIDIA GPU 驱动的机器 2、Docker CE安装 # 删除旧版本的 Docker&#xff08;如果存在&#xff09; sudo yum remove -y docker docker-common docker-selinux docker-engine # 安装必要的软件包&#xff1a; sudo yum install -y yum-utils device-mapper-persiste…

springboot3项目练习详细步骤(第四部分:文件上传、登录优化、多环境开发)

目录 本地文件上传 接口文档 业务实现 登录优化 SpringBoot集成redis 实现令牌主动失效机制 多环境开发 本地文件上传 接口文档 业务实现 创建FileUploadController类并编写请求方法 RestController public class FileUploadController {PostMapping("/upload&…

EPBU/MOBI转PDF

--痛苦 --不爱BB 直接上码。 写了一个java方法&#xff0c;转epub 或者mobi 为 pdf的方法 &#xff08;单个转换&#xff09; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader;public class EbookConvert…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(八)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 15 节&#xff09; P15《14.ArkUI组件-状态管理state装饰器》 回到最初的 Hello World 案例&#xff0c;首先验证 如果删掉 State…

【BSP开发经验】用户态栈回溯技术

前言 在内核中有一个非常好用的函数dump_stack, 该函数在我们调试内核的过程中可以打印出函数调用关系&#xff0c;该函数可以帮助我们进行内核调试&#xff0c;以及让我们了解内核的调用关系。同时当内核发生崩溃的时候就会自己将自己的调用栈输出到串口。 栈回溯非常有利于我…

动态规划(算法)---01.斐波那契数列模型_第N个泰波那契数

前言&#xff1a; 有一个很著名的公式 “程序数据结构算法”。 算法是模型分析的一组可行的&#xff0c;确定的&#xff0c;有穷的规则。通俗的说&#xff0c;算法也可以理解为一个解题步骤&#xff0c;有一些基本运算和规定的顺序构成。但是从计算机程序设计的角度看&#xff…

【计算机网络实验】TCP协议的抓包分析:三次握手四次挥手UDP和TCP的区别(超详细教程)

计算机网络实验——TCP协议抓包分析 文章目录 计算机网络实验——TCP协议抓包分析一、基础知识点1、运输层两个重要协议的特点对比&#xff08;TCP和UDP&#xff09;2、TCP报文的格式3、常见的TCP报文标识字段&#xff08;FLAG字段&#xff09;4、TCP连接的建立过程及理解——三…

RPC原理技术

RPC原理技术 背景介绍起源组件实现工作原理 背景 本文内容大多基于网上其他参考文章及资料整理后所得&#xff0c;并非原创&#xff0c;目的是为了需要时方便查看。 介绍 RPC&#xff0c;Remote Procedure Call&#xff0c;远程过程调用&#xff0c;允许像调用本地方法一样调…