当前位置: 首页 > news >正文

Android Compose: `remember` 与 `ViewModel` 保存数据的优缺点对比

在这里插入图片描述

在开发 Android 应用时,管理 UI 状态是一个不可避免的话题。Jetpack Compose 提供了两种常见的方式来保存和管理数据:rememberViewModel。它们各有优缺点,适用于不同的场景。

本文将详细对比这两者在保存数据时的优缺点,帮助你在实际开发中做出更合适的选择。

rememberViewModel 的基本概念

在深入对比之前,我们先简单回顾一下这两者的基本概念。

remember
remember 是 Jetpack Compose 提供的一个工具,用于在 UI 组件重组(Recomposition)过程中缓存数据。当 UI 被重新绘制时,remember 可以保持一些数据不变,避免不必要的重新计算或数据丢失。

ViewModel
ViewModel 是 Android Architecture Components 中的一个组件,用于在配置更改(如屏幕旋转)时保存和管理 UI 相关的数据。ViewModel 通常与 LiveDataState 一起使用,它的生命周期跨越了 UI 组件的生命周期,能够确保数据在配置更改后不丢失。

remember 的优缺点

优点

  1. 性能优化
    remember 可以缓存数据,避免每次 UI 组件重组时重新计算或重新创建对象。对于一些不经常改变的数据,remember 可以显著提高应用的性能,减少不必要的计算。

  2. 简单易用
    使用 remember 保存数据非常简单,只需将数据放在 remember 的函数体内即可。没有复杂的生命周期管理,非常适合简单的场景。

  3. 轻量级
    remember 不依赖于其他架构组件,不需要创建额外的类或管理额外的线程。它是纯粹的 Compose 解决方案。

缺点

  1. 生命周期局限性
    remember 的作用范围仅限于当前 Composable 函数的生命周期。如果 Composable 被销毁并重新创建,remember 会丢失数据。而 ViewModel 是设计为跨 Activity 或 Fragment 生命周期保存数据的,因此更适合长期持久化的数据。

  2. 适用场景有限
    remember 适用于一些简单的 UI 状态保存,通常不适合保存复杂的业务逻辑或者需要跨多个屏幕共享的数据。对于需要长期保存或跨多个界面共享的数据,ViewModel 更为合适。

  3. 无法处理配置变化
    如果屏幕旋转或其他配置发生变化,remember 中的数据会丢失。而 ViewModel 在这些情况下仍然能够保留数据。

ViewModel 的优缺点

优点

  1. 跨组件生命周期保存数据
    ViewModel 设计用于在配置更改(如屏幕旋转)时保存数据。它的生命周期是与 ActivityFragment 绑定的,因此适用于跨多个界面或组件的共享数据。

  2. 支持复杂的业务逻辑和状态
    ViewModel 更适合保存和管理复杂的业务逻辑和状态。例如,保存从服务器获取的列表数据或用户设置等。

  3. 与 Jetpack 架构组件兼容
    ViewModel 可以与 LiveDataState 等架构组件结合使用,方便处理异步数据流和 UI 状态的变化。

  4. 在配置变化时不丢失数据
    由于 ViewModel 的生命周期是与 ActivityFragment 绑定的,它在配置变化(如屏幕旋转)时不会丢失数据,能够保证数据的持续性。

缺点

  1. 相对复杂
    ViewModel 的使用相对复杂,需要更多的代码和架构设计。如果只是需要在一个 Composable 函数内保存一些简单的数据,remember 会更简洁和高效。

  2. 依赖于 ViewModel 相关框架
    使用 ViewModel 需要依赖 Jetpack 的架构组件,这意味着你需要引入额外的库和依赖,可能增加一些复杂性和包的大小。

  3. 过度设计
    对于一些简单的 UI 状态,使用 ViewModel 可能显得有些过度设计。它更适合需要跨多个界面共享的数据,而对于局部组件的 UI 状态,remember 是一个更轻量的选择。

remember vs ViewModel:何时使用?

我们来总结一下,什么时候适合使用 remember,什么时候适合使用 ViewModel

使用 remember 的场景:

  • 单个 UI 组件的简单状态管理:例如按钮点击次数、输入框内容等,数据只在当前 Composable 中使用,不需要跨多个屏幕共享。
  • 避免不必要的计算:如果你有一些计算比较昂贵的数据,remember 可以在界面重组时缓存该数据,避免每次重组时重新计算。
  • 短生命周期的数据:如果数据只在某个特定 UI 组件生命周期内有效,使用 remember 更合适。

使用 ViewModel 的场景:

  • 跨屏幕共享数据:例如用户登录信息、购物车内容等需要在多个 Activity 或 Fragment 中共享的数据。
  • 需要长期持久化的数据:例如网络请求结果、数据库数据等,即使发生配置变化(如屏幕旋转),数据也不应丢失。
  • 复杂的业务逻辑:如果你需要处理异步数据流、网络请求结果、或者涉及多个 UI 状态的管理,ViewModel 更加合适。

示例代码:rememberViewModel 对比

我们通过一个简单的例子来展示如何使用 rememberViewModel 保存数据。

使用 remember

 @Composablefun RememberExample() {val counter = remember { mutableStateOf(0) }Column(horizontalAlignment = Alignment.CenterHorizontally,modifier = Modifier.padding(16.dp)) {Text("Count: ${counter.value}")Spacer(modifier = Modifier.height(8.dp))Button(onClick = { counter.value++ }) {Text("Increment")}}}

使用 ViewModel

 class CounterViewModel : ViewModel() {private val _counter = mutableStateOf(0)val counter: State<Int> = _counterfun increment() {_counter.value++}}@Composablefun ViewModelExample(viewModel: CounterViewModel = viewModel()) {Column(horizontalAlignment = Alignment.CenterHorizontally,modifier = Modifier.padding(16.dp)) {Text("Count: ${viewModel.counter.value}")Spacer(modifier = Modifier.height(8.dp))Button(onClick = { viewModel.increment() }) {Text("Increment")}}}

结论

remember 和 ViewModel 都是非常有用的工具,但它们适用于不同的场景:

  • remember 适用于保存简单、局部的 UI 状态,尤其是需要优化性能或避免重复计算时。
  • ViewModel 更适合用于跨多个界面共享数据,或者需要在配置变化后保存数据的场景。

在实际开发中,根据数据的生命周期和复杂度来选择合适的工具,能够让你的代码更加简洁高效。如果只是局部的 UI 状态,remember 是一个非常合适的选择;如果是跨界面或需要持久化的数据,ViewModel 会更适合。

相关文章:

Android Compose: `remember` 与 `ViewModel` 保存数据的优缺点对比

在开发 Android 应用时&#xff0c;管理 UI 状态是一个不可避免的话题。Jetpack Compose 提供了两种常见的方式来保存和管理数据&#xff1a;remember 和 ViewModel。它们各有优缺点&#xff0c;适用于不同的场景。 本文将详细对比这两者在保存数据时的优缺点&#xff0c;帮助…...

vue3+vite模式下修改pinia的stroe初始值不进行热HMR更新解析

原因&#xff1a; import { defineStore } from pinia interface CounterState {count: number;name: string; } export const useCounterStore defineStore(counter, {state: () > ({ count: 10, name: Eduardo }),getters: {doubleCount: (state:CounterState) > st…...

【一句话经验】ubuntu vi/vim 模式自动设置为paste

从centos过来&#xff0c;发现ubutun有些地方不习惯&#xff0c;尤其是vi的粘贴&#xff0c;默认自动进去了代码模式&#xff0c;导致每次粘贴必须得set paste&#xff0c;否则会出现问题。 解决办法非常简单&#xff0c;按照下面命令执行即可&#xff1a; cd ~ echo "…...

[杂学笔记] TCP和UDP的区别,对http接口解释 , Cookie和Session的区别 ,http和https的区别 , 智能指针 ,断点续传

文章目录 1. TCP和UDP的区别2. 对http接口解释3. Cookie和Session的区别4. http和https的区别5. 智能指针6.断点续传 1. TCP和UDP的区别 tcp的特点&#xff1a; 面向连接&#xff0c;可靠性高&#xff0c;全双工&#xff0c;面向字节流udp特点&#xff1a;无连接&#xff0c;不…...

训练大模型LLM选择哪种开发语言最好

训练大型语言模型&#xff08;LLM&#xff09;时&#xff0c;选择合适的编程语言主要取决于效率、生态支持、开发便利性以及特定需求&#xff08;如性能优化或硬件适配&#xff09;。以下是常见语言的分析和推荐&#xff1a; --- 1. Python&#xff08;首选语言&#xff09; 优…...

Jupyter Notebook 全平台安装与配置教程(附Python/Anaconda双方案)

一、软件定位与特性 Jupyter Notebook 是交互式编程与数据科学分析工具&#xff0c;支持 40 编程语言&#xff0c;其基于浏览器的「代码块可视化」工作流&#xff0c;已成为机器学习、数据清洗、学术研究的标准环境。核心优势包括&#xff1a; 实时执行代码片段并保存结果支持…...

AutoDL平台租借GPU,创建transformers环境,使用VSCode SSH登录

AutoDL平台租借GPU&#xff0c;创建transformers环境&#xff0c;使用VSCode SSH登录 一、AutoDl平台租用GPU 1.注册并登录AutoDl官网&#xff1a;https://www.autodl.com/home 2.选择算力市场&#xff0c;找到需要的GPU&#xff1a; 我这里选择3090显卡 3.这里我们就选择P…...

【Java篇】行云流水,似风分岔:编程结构中的自然法则

文章目录 Java 程序逻辑控制&#xff1a;顺序、分支与循环结构全面解析一、顺序结构二、分支结构2.1 if 语句2.1.1 基本语法2.1.2 if-else 语句2.1.3 if-else if-else 语句 2.2 switch 语句 三、循环结构3.1 while 循环3.2 break 语句3.3 continue 语句3.4 for 循环 四、输入输…...

2.4 基于Vitest的单元测试基础设施搭建

文章目录 1. 现代单元测试体系解析测试金字塔演进Vitest核心定位2. 基础设施架构设计整体架构图3. 环境配置全流程3.1 基础环境搭建3.2 配置文件`vitest.config.ts`3.3 测试环境初始化4. 测试用例编写规范4.1 基础测试示例4.2 Vue组件测试4.3 异步逻辑测试5. Mock策略深度优化5…...

SqlSugar 进阶之原生Sql操作与存储过程写法 【ORM框架】

系列文章目录 &#x1f380;&#x1f380;&#x1f380; .NET开源 ORM 框架 SqlSugar 系列 &#x1f380;&#x1f380;&#x1f380; 文章目录 系列文章目录一、前言 &#x1f343;二、用法介绍三、方法列表四、使用案例五、调用存储过程六、in参数用法七、SqlServer带Go的脚…...

Navicat Premium(数据库管理工具) v17.1.13 中文 Windows

介绍 Navicat Premium 是一款多功能的数据库管理工具&#xff0c;可以连接并管理主流的数据库系统&#xff0c;如MySQL、PostgreSQL、Oracle、SQL Server等。它提供了丰富的功能和强大的工具&#xff0c;可以帮助用户轻松地管理数据库&#xff0c;进行数据导入导出、查询、备份…...

IDEA(十一)调整新版本的工具栏显示Git操作(pull、commit、push、revert等)

目录 一、背景二、操作步骤2.1 开启新 UI 样式2.2 设置 Tool Window 工具栏 一、背景 好久没有更新 IDEA 了&#xff0c;更新之后发现 IDEA 的工具栏消失了。一番操作之后&#xff0c;终于把 IDEA 的工具栏的设置调整好了&#xff0c;在此进行记录调整步骤&#xff0c;供大家学…...

QoS质量配置

他们祝你挺拔&#xff0c;再挺拔一点&#xff1b;我只祝你&#xff0c;永远年少&#xff0c;永远一骑当先. 1. QoS的概念 QoS(服务质量)是指一个网络能够利用各种各样的基础技术向选定的网络通信提供更好 的服务的能力。这些基础技术包括&#xff1a;帧中继&#xff08;FrameR…...

2024年群智能SCI1区TOP:混沌可行性恢复粒子群算法CEPSO,深度解析+性能实测

目录 1.摘要2.改进策略3.结果展示4.参考文献5.代码获取 1.摘要 本文研究了解决二阶段非线性固定费用运输问题&#xff08;Two-stage NFCTP&#xff09;&#xff0c;该问题的特点是每条运输弧线都与固定费用和与运输量的平方成正比的变量费用相关联。由于涉及固定费用和非线性组…...

ORACLE EBS数据库RELINK方式搭建克隆环境

ORACLE EBS系统的数据库&#xff0c;一般都安装了很多特定功能的小补丁来解决特定的BUG&#xff1b;因此对于已经安装好的系统&#xff0c;想要克隆一套测试环境、搭建一个新的备机做测试等&#xff0c;如果按照生产环境标准&#xff0c;则需要安装大量补丁&#xff0c;带来很大…...

第十五届蓝桥杯省赛电子类单片机学习过程记录(客观题)

客观试题: 01.典型的BUCK电源电路包含哪些关键器件(ABCD) A. 电容 B. 二极管 C. 电感 D. MOSFET 解析: 典型的 BUCK 电源电路是一种降压型的直流-直流转换电路,它包含以下关键器件: A.电容:电容在电路中起到滤波的作用。输入电容用于平滑输入电压的波动,减少电源噪声对…...

使用 invideo ai 实现文生视频

https://ai.invideo.io 然后选ai生成视频 输入描述&#xff0c;点击生成 就可以得到视频了&#xff0c;可以下载...

5G技术与物联网融合:未来智慧城市的基石

一、智慧城市演进&#xff1a;从概念到落地的技术革命 1.1 全球智慧城市发展现状 2023年全球智慧城市市场规模突破$1.2万亿美元&#xff0c;中国以35%的占比领跑市场&#xff08;数据来源&#xff1a;IDC&#xff09;。典型应用成效&#xff1a; 交通效率&#xff1a;新加坡…...

蓝桥杯备赛-差分-重新排序

问题描述 给定一个数组 AA 和一些查询 Li,RiLi​,Ri​, 求数组中第 LiLi​ 至第 RiRi​ 个元素之和。 小蓝觉得这个问题很无聊, 于是他想重新排列一下数组, 使得最终每个查 询结果的和尽可能地大。小蓝想知道相比原数组, 所有查询结果的总和最多可 以增加多少? 输入格式 输…...

使用DeepSeek+蓝耘快速设计网页简易版《我的世界》小游戏

前言&#xff1a;如今&#xff0c;借助先进的人工智能模型与便捷的云平台&#xff0c;即便是新手开发者&#xff0c;也能开启创意游戏的设计之旅。DeepSeek 作为前沿的人工智能模型&#xff0c;具备强大的功能与潜力&#xff0c;而蓝耘智算云平台则为其提供了稳定高效的运行环境…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...