手工做衣服网站/网络营销的方式
前言
在Compose的学习中,我们在可组合函数中使用rememberSaveable保存应用数据,但这可能意味着将逻辑保留在可组合函数中或附近。随着应用体量不断变大,您应将数据和逻辑从可组合函数中移出。
而在之前的应用架构学习中,我们接触到了MVVM架构,他将应用数据存储在了ViewModel中,它是Android Jetpack 库中的架构组件之一。
当框架在配置更改或其他事件期间销毁并重新创建 activity 时,存储的数据不会丢失。不过,如果 activity 因进程终止而被销毁,数据将会丢失。ViewModel 只能通过快速重新创建 activity 缓存数据。
了解应用架构
架构原则
最常用的架构原则包括:分离关注点和通过模型驱动界面。
- 分离关注点:该原则指出,应将应用分为函数类,每个类有各自的职责
- 通过模型驱动界面:该原则指出,应该通过模型驱动界面,最好是持久性模型
模型是负责处理应用数据的组件。它们独立于应用中的界面元素和应用组件,因此不受应用的生命周期以及相关的关注点的影响。
推荐的应用架构
基于上面两点原则,每个应用应至少有两个层:
- 界面层:屏幕上显示应用数据,但独立于数据层的层
- 数据层:用于存储、检索和提供应用数据的层
每当数据因用户互动(例如按了某个按钮)而发生变化时,界面都应随之更新,以反映这些变化。
界面层由以下组件组成:
- 界面元素:用于在屏幕上呈现数据的组件。您将使用 Compose 构建这些元素。
- 状态容器:用于保存数据、向界面提供数据以及处理应用逻辑的组件。此处我们使用 ViewModel
ViewModel
简介
ViewModel组件用于存储和公开界面所使用的状态(UI State)。
界面状态(UI State)是经过ViewModel转换的应用数据。界面(UI)是相对于用户而言的,界面状态是相对于应用而言的,例如一个开关switch展现在用户面前,而switch是开还是关,就是switch的界面状态。因此,对于界面状态的任何改变,都会直接影响界面。
ViewModel会存储应用相关的数据,这些数据不会在activity被销毁并重新创建时被销毁。应用会在配置更改期间自动保留ViewModel对象,以便在重组时ViewModel存储的数据可以立即被使用。
与Compose梦幻联动
在使用Compose时,ViewModel是向可组合项展示界面状态的主要方式。过去我们将数据的存储和处理方式留在activity或fragment中,臃肿而不直观;如今在混合应用中,activity和fragment仅用于托管可组合函数。
添加ViewModel
以下是用户掷骰子屏幕的 ViewModel 实现示例。
1. 打开app模块下的build.gradle.kts,在dependencies块添加如下内容:
dependencies {
// other dependenciesimplementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
//...
}
2. 添加一个数据类存储各项值,并创建一个类继承ViewModel:
//数据类,存储游戏的值
data class DiceUiState(val firstDieValue: Int? = null,val secondDieValue: Int? = null,val numberOfRolls: Int = 0,
)class DiceRollViewModel : ViewModel() {// 展示界面状态// 此处的StateFlow是数据容器式可观察数据流,其value属性反映了当前的状态值// 有了它,可组合函数就可以监听界面状态更新//防止外部类修改ViewModel的数据,设置为private,同时val类型不包含setter,为只读属性private val _uiState = MutableStateFlow(DiceUiState())//asStateFlow方法使可变状态流变为只读状态流,界面通过只读属性的uiState读取值val uiState: StateFlow<DiceUiState> = _uiState.asStateFlow()// 处理业务逻辑fun rollDice() {_uiState.update { currentState ->//调用 copy 方法来创建新的 DiceState 对象,并将其赋值给 uiState 变量。//这将触发 UI 的重新渲染。currentState.copy(firstDieValue = Random.nextInt(from = 1, until = 7),secondDieValue = Random.nextInt(from = 1, until = 7),numberOfRolls = currentState.numberOfRolls + 1,)}}
}
3. 从activity访问ViewModel:
//Compose写法
import androidx.lifecycle.viewmodel.compose.viewModel// Use the 'viewModel()' function from the lifecycle-viewmodel-compose artifact
@Composable
fun DiceRollScreen(viewModel: DiceRollViewModel = viewModel()
) {val uiState by viewModel.uiState.collectAsStateWithLifecycle()// Update UI elements
}//Kotlin写法
import androidx.activity.viewModelsclass DiceRollActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {// 在系统第一次调用Activity的onCreate()方法时创建一个 ViewModel实例// 重新创建的activity会收到相同的、第一次创建activity时留下的ViewModel实例// 此处使用了'by viewModels()'的Kotlin属性委托// 他创建并初始化与activity相关联的ViewModelval viewModel: DiceRollViewModel by viewModels()lifecycleScope.launch {repeatOnLifecycle(Lifecycle.State.STARTED) {viewModel.uiState.collect {// 在此处更新ui元素}}}}
}
ViewModel的生命周期
ViewModel的生命周期与其作用域直接相关。作用域指的是ViewModel处理的组件,如activity、fragment、navigation。
以 activity为例,当进入onCreate方法,ViewModel的生命周期随之开始;而进入onDestroy方法、activity即将被销毁时,ViewModel也进入了它生命周期的最后一个方法:onCleared方法。
ViewModel会一直保存在内存中,直到其作用域ViewModelStoreOwner消失。这使得 ViewModels 成为了存储在配置更改后仍然存在的数据的绝佳解决方案。
清除 ViewModel 依赖项
当 ViewModelStoreOwner 在 ViewModel 的生命周期内销毁 ViewModel 时,ViewModel 会调用 onCleared 方法。这样,您就可以清理遵循 ViewModel 生命周期的任何工作或依赖项。
以广播接收器为例,我们可以重写onClear方法以注销它:
class TestViewModel(context: Application) : AndroidViewModel(context) {private var receiver : BroadcastReceiver ? = null...override fun onCleared() {super.onCleared()receiver?.unregister()}
}
相关文章:

Android的ViewModel
前言 在Compose的学习中,我们在可组合函数中使用rememberSaveable保存应用数据,但这可能意味着将逻辑保留在可组合函数中或附近。随着应用体量不断变大,您应将数据和逻辑从可组合函数中移出。 而在之前的应用架构学习中&…...

Android 圆环带刻度条进度动画效果实现
效果图 需求是根据传感器做一个重力球效果,先实现了动画后续加上跟传感器联动. 又是摆烂的一天, 尚能呼吸,未来可期啊 View源码 package com.android.circlescalebar.view;import android.content.Context; import android.content.res.Typ…...

94. 二叉树的中序遍历
// 定义一个名为Solution的类,用于解决二叉树的中序遍历问题 class Solution { // 定义一个公共方法,输入是一个二叉树的根节点,返回一个包含中序遍历结果的整数列表 public List<Integer> inorderTraversal(TreeNode root) { // …...

汽车信息安全概述
随着智能网联汽车的迅猛发展,车辆不再是简单的交通工具,而是集数据收集、处理与通信于一体的移动智能终端。然而,这一变革也使得汽车成为黑客攻击的新目标。汽车信息安全问题日益凸显,成为行业关注的焦点。本文将深入探讨汽车信息…...

Linux——基础IO
📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、C语言IO1、写文件2、读文件3、stdin & stdout & stderr 二、系统文件I/O1、写文件…...

数据结构-数组
一,数组基础及注意事项 1,用来储存一组相同的类型的数据. 2,在内存中,分配连续的空姐,数组创建时要指定容量(大小). 3,创建格式: 数据类型 []数组名 int[] arr new int[10] int[] arr2 {1,2,3,4}. 4,索引--访问数组时通过索引进行操作. (注意:一定要理解索引的含义,在数据结…...

【Java程序设计】【C00279】基于Springboot的智慧外贸平台(有论文)
基于Springboot的智慧外贸平台(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的智慧外贸平台 本系统分为系统功能模块、管理员功能模块、买家功能模块以及商家功能模块。 系统功能模块:在平台首页可以…...

C#,计算几何,计算机图形学(Computer Graphics)洪水填充算法(Flood Fill Algorithm)与源代码
1 泛洪填充算法(Flood Fill Algorithm) 泛洪填充算法(Flood Fill Algorithm) ,又称洪水填充算法,是在很多图形绘制软件中常用的填充算法,最熟悉不过就是 windows 自带画图软件的油漆桶功能。 2 源程序 using System; using System.Collecti…...

C# 实现网页内容保存为图片并生成压缩包
目录 应用场景 实现代码 扩展功能(生成压缩包) 小结 应用场景 我们在一个求职简历打印的项目功能里,需要根据一定的查询条件,得到结果并批量导出指定格式的文件。导出的格式可能有多种,比如WORD格式、EXCEL格式、PDF格式等,…...

C#_事件简述
事件模型简述 C#中事件的运行模式为"发布订阅模型",事件触发者称为"发布者",事件处理者称为"订阅者" 事件模型的五个组成部分 事件(成员)事件的拥有者(类/对象)事件的响应…...

C语言:指针(一)
目录 1.内存和地址2. 指针变量和地址2.1 取地址操作符(&)2.2 指针变量和解引用操作符(*)2.2.1 指针变量2.2.2 解引用操作符(*) 2.3 指针变量的大小 3.指针变量的类型和意义3.1 指针的解引用3.2 指针 -指…...

【leetcode刷题之路】面试经典150题(3)——哈希表+区间
文章目录 5 哈希表5.1 【哈希表】赎金信5.2 【数学】同构字符串5.3 【数学】单词规律5.4 【哈希表】有效的字母异位词5.5 【哈希表】字母异位词分组5.6 【双指针】两数之和5.7 【数学】快乐数5.8 【哈希表】219. 存在重复元素 II5.9 【数学】最长连续序列 6 区间6.1 【数学】汇…...

群晖NAS DSM7.2.1安装宝塔之后无法登陆账号密码问题解决
宝塔的安装就不在这赘述了,只说下,启动之后默认账号密码无法登陆的问题。 按照上面给出的账号密码,无法登陆 然后点忘记密码,由于是docker安装的,根目录下没有/www/server/panel 。 也没有bt命令 要怎么修改呢。 既然…...

9、使用 ChatGPT 的 GPT 制作自己的 GPT!
使用 ChatGPT 的 GPT 制作自己的 GPT! 想用自己的 GPT 超越 GPT ChatGPT 吗?那么让我们 GPT GPT 吧! 山姆 奥特曼利用这个机会在推特上宣传 GPTs 的同时还猛烈抨击了埃隆的格罗克。 GPTs概览 他们来了! 在上周刚刚宣布之后,OpenAI 现在推出了其雄心勃勃的新 ChatGPT…...

企业微信应用开发:使用Cpolar域名配置进行本地接口回调的调试指南
文章目录 1. Windows安装Cpolar2. 创建Cpolar域名3. 创建企业微信应用4. 定义回调本地接口5. 回调和可信域名接口校验6. 设置固定Cpolar域名7. 使用固定域名校验 企业微信开发者在应用的开发测试阶段,应用服务通常是部署在开发环境,在有数据回调的开发场…...

js 可选链运算符(?.)空值合并运算符(??)逻辑空赋值运算符(??=)
可选链运算符(?.)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 运算符的功能类似于 . 链式运算符,不同之处在于,在引用为空 (nullish ) (null 或者 undefined) 的情况下不会引起…...

vue 手势解锁功能
效果 实现 <script setup lang"ts"> const canvasRef ref<HTMLCanvasElement>() const ctx ref<CanvasRenderingContext2D | null>(null) const width px2px(600) const height px2px(700) const radius ref(px2px(50))const init () > …...

介绍 CI / CD
目录 一、介绍 CI / CD 1、为什么要 CI / CD 方法简介 1、持续集成 2、持续交付 3、持续部署 2、GitLab CI / CD简介 3、GitLab CI / CD 的工作原理 4、基本CI / CD工作流程 5、首次设置 GitLab CI / CD 6、GitLab CI / CD功能集 一、介绍 CI / CD 在本文档中&#x…...

Stable Diffusion 3 Early Preview发布
2月22日,Stability AI 发布了 Stable Diffusion 3 early preview,这是一种开放权重的下一代图像合成模型。据报道,它继承了其前身,生成了详细的多主题图像,并提高了文本生成的质量和准确性。这一简短的公告并未附带公开…...

【解决(几乎)任何机器学习问题】:特征选择
当你创建了成千上万个特征后,就该从中挑选出⼏个了。但是,我们绝不应该创建成百上千个⽆⽤的特征。特征过多会带来⼀个众所周知的问题,即 "维度诅咒"。如果你有很多特征,你也必须有很多训练样本来捕捉所有特征。什么是 …...

24 双非计算机秋招总结
引言 我整理了一份 10w 字数的前端技术文档(飞书),地址:https://qx8wba2yxsl.feishu.cn/docx/Vb5Zdq7CGoPAsZxMLztc53E1n0k?fromfrom_copylink,欢迎对前端感兴趣的同学查看、共建、分享。 PS:我是一名大四…...

用友NC65与用友NCC对接集成NC65-凭证列表查询打通凭证新增
用友NC65与用友NCC对接集成NC65-凭证列表查询打通凭证新增 数据源平台:用友NC65 用友NC是为集团与行业企业提供的全线管理软件产品,由亚太本土最大的企业管理软件提供商用友公司研发提供,用友NC率先采用J2EE架构和先进开放的集团级开发平台UAP࿰…...

【初中生讲机器学习】12. 似然函数和极大似然估计:原理、应用与代码实现
创建时间:2024-02-23 最后编辑时间:2024-02-24 作者:Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏,很高兴遇见你~ 我是 Geeker_LStar,一名初三学生,热爱计算机和数学,我们一起加…...

【达梦数据库】查看pesg回滚段信息的视图和SQL
一些达梦回滚段是使用情况的查询SQL,供排查“回滚记录版本太旧,无法获取用户记录” 等类似问题时使用 视图名说明主库备库v$pseg_items显示回滚系统中当前回滚项信息(回滚线程的工作信息)总行数WORKER_THREADS1查询 no rowsv$pseg…...

UML---活动图
活动图概述 活动图(Activity Diagram)是UML(Unified Modeling Language,统一建模语言)中的一种行为建模工具,主要用于描述系统或业务流程中的一系列活动或操作。活动图通常用于描述用例中的行为,…...

编程笔记 Golang基础 018 常量与变量
编程笔记 Golang基础 018 常量与变量 一、常量常量的定义iota特性 二、变量变量定义变量作用域零值与初始化类型转换注意事项 三、重要性 常量,就是在程序编译阶段就确定下来的值,而程序在运行时则无法改变该值。变量是程序的基本组成单位,用…...

如何使用Douglas-042为威胁搜索和事件应急响应提速
关于Douglas-042 Douglas-042是一款功能强大的PowerShell脚本,该脚本可以提升数据分类的速度,并辅助广大研究人员迅速从取证数据中筛选和提取出关键数据。 该工具能够搜索和识别Windows生态系统中潜在的安全漏洞,Douglas-042会将注意力放在…...

华为配置WLAN AC和AP之间VPN穿越示例
配置WLAN AC和AP之间VPN穿越示例 组网图形 图1 配置WLAN AC和AP之间VPN穿越示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 企业用户接入WLAN网络,以满足移动办公的最基本需求。且在覆盖区域内移动发生漫游时,不影响…...

跨语言的序列化与反序列化
在Java中实现跨语言的序列化与反序列化通常可以采用以下几种方式 使用标准的跨语言序列化格式 可以选择使用一些标准的跨语言序列化格式,例如JSON、XML、Protocol Buffers(ProtoBuf)等。这些格式都是跨语言的,可以方便地在不同的编程语言之间进行数据交换。在Java中,可以…...

软考-中级-系统集成2023年综合知识(三)
🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 软考中级专栏回顾 专栏…...