Android Compose: `remember` 与 `ViewModel` 保存数据的优缺点对比
在开发 Android 应用时,管理 UI 状态是一个不可避免的话题。Jetpack Compose 提供了两种常见的方式来保存和管理数据:remember
和 ViewModel
。它们各有优缺点,适用于不同的场景。
本文将详细对比这两者在保存数据时的优缺点,帮助你在实际开发中做出更合适的选择。
remember
和 ViewModel
的基本概念
在深入对比之前,我们先简单回顾一下这两者的基本概念。
remember
:
remember
是 Jetpack Compose 提供的一个工具,用于在 UI 组件重组(Recomposition)过程中缓存数据。当 UI 被重新绘制时,remember
可以保持一些数据不变,避免不必要的重新计算或数据丢失。
ViewModel
:
ViewModel
是 Android Architecture Components 中的一个组件,用于在配置更改(如屏幕旋转)时保存和管理 UI 相关的数据。ViewModel
通常与 LiveData
或 State
一起使用,它的生命周期跨越了 UI 组件的生命周期,能够确保数据在配置更改后不丢失。
remember
的优缺点
优点
-
性能优化:
remember
可以缓存数据,避免每次 UI 组件重组时重新计算或重新创建对象。对于一些不经常改变的数据,remember
可以显著提高应用的性能,减少不必要的计算。 -
简单易用:
使用remember
保存数据非常简单,只需将数据放在remember
的函数体内即可。没有复杂的生命周期管理,非常适合简单的场景。 -
轻量级:
remember
不依赖于其他架构组件,不需要创建额外的类或管理额外的线程。它是纯粹的 Compose 解决方案。
缺点
-
生命周期局限性:
remember
的作用范围仅限于当前 Composable 函数的生命周期。如果 Composable 被销毁并重新创建,remember
会丢失数据。而ViewModel
是设计为跨 Activity 或 Fragment 生命周期保存数据的,因此更适合长期持久化的数据。 -
适用场景有限:
remember
适用于一些简单的 UI 状态保存,通常不适合保存复杂的业务逻辑或者需要跨多个屏幕共享的数据。对于需要长期保存或跨多个界面共享的数据,ViewModel
更为合适。 -
无法处理配置变化:
如果屏幕旋转或其他配置发生变化,remember
中的数据会丢失。而ViewModel
在这些情况下仍然能够保留数据。
ViewModel
的优缺点
优点
-
跨组件生命周期保存数据:
ViewModel
设计用于在配置更改(如屏幕旋转)时保存数据。它的生命周期是与Activity
或Fragment
绑定的,因此适用于跨多个界面或组件的共享数据。 -
支持复杂的业务逻辑和状态:
ViewModel
更适合保存和管理复杂的业务逻辑和状态。例如,保存从服务器获取的列表数据或用户设置等。 -
与 Jetpack 架构组件兼容:
ViewModel
可以与LiveData
、State
等架构组件结合使用,方便处理异步数据流和 UI 状态的变化。 -
在配置变化时不丢失数据:
由于ViewModel
的生命周期是与Activity
或Fragment
绑定的,它在配置变化(如屏幕旋转)时不会丢失数据,能够保证数据的持续性。
缺点
-
相对复杂:
ViewModel
的使用相对复杂,需要更多的代码和架构设计。如果只是需要在一个 Composable 函数内保存一些简单的数据,remember
会更简洁和高效。 -
依赖于 ViewModel 相关框架:
使用ViewModel
需要依赖 Jetpack 的架构组件,这意味着你需要引入额外的库和依赖,可能增加一些复杂性和包的大小。 -
过度设计:
对于一些简单的 UI 状态,使用ViewModel
可能显得有些过度设计。它更适合需要跨多个界面共享的数据,而对于局部组件的 UI 状态,remember
是一个更轻量的选择。
remember
vs ViewModel
:何时使用?
我们来总结一下,什么时候适合使用 remember
,什么时候适合使用 ViewModel
。
使用 remember
的场景:
- 单个 UI 组件的简单状态管理:例如按钮点击次数、输入框内容等,数据只在当前 Composable 中使用,不需要跨多个屏幕共享。
- 避免不必要的计算:如果你有一些计算比较昂贵的数据,
remember
可以在界面重组时缓存该数据,避免每次重组时重新计算。 - 短生命周期的数据:如果数据只在某个特定 UI 组件生命周期内有效,使用
remember
更合适。
使用 ViewModel
的场景:
- 跨屏幕共享数据:例如用户登录信息、购物车内容等需要在多个 Activity 或 Fragment 中共享的数据。
- 需要长期持久化的数据:例如网络请求结果、数据库数据等,即使发生配置变化(如屏幕旋转),数据也不应丢失。
- 复杂的业务逻辑:如果你需要处理异步数据流、网络请求结果、或者涉及多个 UI 状态的管理,
ViewModel
更加合适。
示例代码:remember
与 ViewModel
对比
我们通过一个简单的例子来展示如何使用 remember
和 ViewModel
保存数据。
使用 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 应用时,管理 UI 状态是一个不可避免的话题。Jetpack Compose 提供了两种常见的方式来保存和管理数据:remember 和 ViewModel。它们各有优缺点,适用于不同的场景。 本文将详细对比这两者在保存数据时的优缺点,帮助…...

vue3+vite模式下修改pinia的stroe初始值不进行热HMR更新解析
原因: 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过来,发现ubutun有些地方不习惯,尤其是vi的粘贴,默认自动进去了代码模式,导致每次粘贴必须得set paste,否则会出现问题。 解决办法非常简单,按照下面命令执行即可: 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的特点: 面向连接,可靠性高,全双工,面向字节流udp特点:无连接,不…...
训练大模型LLM选择哪种开发语言最好
训练大型语言模型(LLM)时,选择合适的编程语言主要取决于效率、生态支持、开发便利性以及特定需求(如性能优化或硬件适配)。以下是常见语言的分析和推荐: --- 1. Python(首选语言) 优…...

Jupyter Notebook 全平台安装与配置教程(附Python/Anaconda双方案)
一、软件定位与特性 Jupyter Notebook 是交互式编程与数据科学分析工具,支持 40 编程语言,其基于浏览器的「代码块可视化」工作流,已成为机器学习、数据清洗、学术研究的标准环境。核心优势包括: 实时执行代码片段并保存结果支持…...

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

【Java篇】行云流水,似风分岔:编程结构中的自然法则
文章目录 Java 程序逻辑控制:顺序、分支与循环结构全面解析一、顺序结构二、分支结构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框架】
系列文章目录 🎀🎀🎀 .NET开源 ORM 框架 SqlSugar 系列 🎀🎀🎀 文章目录 系列文章目录一、前言 🍃二、用法介绍三、方法列表四、使用案例五、调用存储过程六、in参数用法七、SqlServer带Go的脚…...

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

IDEA(十一)调整新版本的工具栏显示Git操作(pull、commit、push、revert等)
目录 一、背景二、操作步骤2.1 开启新 UI 样式2.2 设置 Tool Window 工具栏 一、背景 好久没有更新 IDEA 了,更新之后发现 IDEA 的工具栏消失了。一番操作之后,终于把 IDEA 的工具栏的设置调整好了,在此进行记录调整步骤,供大家学…...
QoS质量配置
他们祝你挺拔,再挺拔一点;我只祝你,永远年少,永远一骑当先. 1. QoS的概念 QoS(服务质量)是指一个网络能够利用各种各样的基础技术向选定的网络通信提供更好 的服务的能力。这些基础技术包括:帧中继(FrameR…...

2024年群智能SCI1区TOP:混沌可行性恢复粒子群算法CEPSO,深度解析+性能实测
目录 1.摘要2.改进策略3.结果展示4.参考文献5.代码获取 1.摘要 本文研究了解决二阶段非线性固定费用运输问题(Two-stage NFCTP),该问题的特点是每条运输弧线都与固定费用和与运输量的平方成正比的变量费用相关联。由于涉及固定费用和非线性组…...
ORACLE EBS数据库RELINK方式搭建克隆环境
ORACLE EBS系统的数据库,一般都安装了很多特定功能的小补丁来解决特定的BUG;因此对于已经安装好的系统,想要克隆一套测试环境、搭建一个新的备机做测试等,如果按照生产环境标准,则需要安装大量补丁,带来很大…...

第十五届蓝桥杯省赛电子类单片机学习过程记录(客观题)
客观试题: 01.典型的BUCK电源电路包含哪些关键器件(ABCD) A. 电容 B. 二极管 C. 电感 D. MOSFET 解析: 典型的 BUCK 电源电路是一种降压型的直流-直流转换电路,它包含以下关键器件: A.电容:电容在电路中起到滤波的作用。输入电容用于平滑输入电压的波动,减少电源噪声对…...

使用 invideo ai 实现文生视频
https://ai.invideo.io 然后选ai生成视频 输入描述,点击生成 就可以得到视频了,可以下载...
5G技术与物联网融合:未来智慧城市的基石
一、智慧城市演进:从概念到落地的技术革命 1.1 全球智慧城市发展现状 2023年全球智慧城市市场规模突破$1.2万亿美元,中国以35%的占比领跑市场(数据来源:IDC)。典型应用成效: 交通效率:新加坡…...
蓝桥杯备赛-差分-重新排序
问题描述 给定一个数组 AA 和一些查询 Li,RiLi,Ri, 求数组中第 LiLi 至第 RiRi 个元素之和。 小蓝觉得这个问题很无聊, 于是他想重新排列一下数组, 使得最终每个查 询结果的和尽可能地大。小蓝想知道相比原数组, 所有查询结果的总和最多可 以增加多少? 输入格式 输…...

使用DeepSeek+蓝耘快速设计网页简易版《我的世界》小游戏
前言:如今,借助先进的人工智能模型与便捷的云平台,即便是新手开发者,也能开启创意游戏的设计之旅。DeepSeek 作为前沿的人工智能模型,具备强大的功能与潜力,而蓝耘智算云平台则为其提供了稳定高效的运行环境…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...

高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...
在Spring Boot中集成RabbitMQ的完整指南
前言 在现代微服务架构中,消息队列(Message Queue)是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个流行的消息中间件,支持多种消息协议,具有高可靠性和可扩展性。 本博客将详细介绍如何在 Spring Boot 项目…...