news 2026/10/23 11:25:53

【Jetpack Compose基础语法学与练】第8课 rememberSaveable,页面旋转/系统重建保留状态

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Jetpack Compose基础语法学与练】第8课 rememberSaveable,页面旋转/系统重建保留状态

前言

上一课学习了 if 条件渲染和 LazyColumn 懒加载列表,掌握动态UI与长列表渲染。
我们一直用 remember 保存状态,但它有一个致命缺陷:手机旋转屏幕、系统因内存不足重建Activity时,remember保存的数据会全部丢失,重置为初始值。
本课学习 rememberSaveable ,它能在系统重建(配置变更、进程重启)时自动保存和恢复状态,是真实安卓开发必须掌握的知识点。

前置:完成1~7课,掌握remember、状态、基础布局与列表

一、完整可运行示例源码

packagecom.example.composefirstimportandroid.os.Bundleimportandroidx.activity.ComponentActivityimportandroidx.activity.compose.setContentimportandroidx.compose.foundation.layout.Columnimportandroidx.compose.foundation.layout.Spacerimportandroidx.compose.foundation.layout.heightimportandroidx.compose.foundation.layout.paddingimportandroidx.compose.material3.Buttonimportandroidx.compose.material3.Textimportandroidx.compose.runtime.Composableimportandroidx.compose.runtime.getValueimportandroidx.compose.runtime.mutableIntStateOfimportandroidx.compose.runtime.saveable.rememberSaveableimportandroidx.compose.runtime.setValueimportandroidx.compose.ui.Modifierimportandroidx.compose.ui.tooling.preview.Previewimportandroidx.compose.ui.unit.dpclassMainActivity:ComponentActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContent{SaveableDemoPage()}}}@ComposablefunSaveableDemoPage(){// rememberSaveable:系统重建时自动保存恢复varcountbyrememberSaveable{mutableIntStateOf(0)}Column(modifier=Modifier.padding(20.dp)){Text(text="当前计数:$count")Spacer(modifier=Modifier.height(12.dp))Button(onClick={count++}){Text("+1")}Spacer(modifier=Modifier.height(8.dp))Button(onClick={count=0}){Text("重置")}}}@Preview@ComposablefunSaveablePreview(){SaveableDemoPage()}

二、逐行代码解读

  1. rememberSaveable { mutableIntStateOf(0) }
    和 remember 用法几乎一模一样,唯一区别:数据会被序列化保存到Bundle中,Activity因配置变更、系统重建的时候,可以自动恢复数据。
    导入路径: androidx.compose.runtime.saveable.rememberSaveable
  2. remember 丢失数据的场景
    旋转屏幕、切换系统深色模式、修改系统字体大小、切换系统语言,这些操作都会触发安卓配置变更,销毁并且重建Activity。
    remember仅仅保存在运行时内存当中,页面重建之后内存清空,状态直接归零。
  3. rememberSaveable 底层原理
    封装安卓原生 onSaveInstanceState 保存机制,把状态序列化放进Bundle,页面重建之后,从Bundle读取数据恢复状态。
    存在功能限制:只能存储可以序列化的数据。整型、字符串、布尔值等基础类型开箱即用;自定义实体类需要实现Parcelable,或者手动提供Saver保存器。
  4. 简单区分 rememberSaveable 和 ViewModel
    rememberSaveable 适合少量UI状态,开箱即用,代码简短。
    ViewModel 适合大批量业务数据、跨页面共享数据,生命周期更长,旋转屏幕不会丢失。ViewModel属于架构进阶内容,后续课程再详细讲解。

三、核心概念文字对比

remember:重组的时候可以保留状态;屏幕旋转、页面重建数据丢失;数据类型没有限制;适合页面临时状态。
rememberSaveable:重组的时候可以保留状态;屏幕旋转、页面重建自动恢复;数据需要支持序列化;适合表单、计数器等需要防丢失的数据。

记忆口诀:临时状态用remember,怕丢数据用rememberSaveable。

四、综合练习题

填空题

  1. 能够在旋转屏幕、系统重建时自动保存恢复状态的函数是________。
  2. rememberSaveable 底层基于安卓传统的________机制,把数据存入Bundle。
  3. rememberSaveable 要求保存的数据类型必须是________的,自定义类需要实现Parcelable。

答案与解析

  1. rememberSaveable ;解析:专门用于跨配置变更、系统重建保存状态。
  2. onSaveInstanceState ;解析:安卓传统保存实例状态机制,Compose封装后自动调用。
  3. 可序列化;解析:Bundle只能存可序列化数据,基础类型默认支持,自定义类需Parcelable。

判断题

  1. remember 和 rememberSaveable 在普通重组时都能保留数据,效果一样。()

答案:正确。理由:两者在Compose重组时都会保存数据,区别只在系统重建场景。

  1. 用remember保存的计数器,旋转屏幕后数值会重置为初始值。()

答案:正确。理由:remember只存在内存中,Activity销毁重建后内存数据清空。

  1. rememberSaveable 可以保存任意类型的数据,包括不可序列化的对象。()

答案:错误。理由:rememberSaveable基于Bundle存储,数据必须可序列化,不可序列化对象会运行时报错。

简答题

  1. 什么场景下应该使用rememberSaveable而不是remember?举两个实际例子。

参考答案:
当状态需要在系统重建(旋转屏幕、语言切换、深色模式切换、内存回收重建)后保留时使用。
例子1:用户在表单页输入了一半内容,旋转屏幕后不能清空;
例子2:计数器页面,用户点了很多次,旋转屏幕后数值要保留。

代码实操题

把第7课的待办列表示例改造:输入文本和待办列表都使用rememberSaveable保存,确保旋转屏幕后数据不丢失。写出关键状态定义代码。参考答案

@ComposablefunTodoListPage(){varinputTextbyrememberSaveable{mutableStateOf("")}vartodoListbyrememberSaveable{mutableStateOf(listOf<String>())}funaddTodo(item:String){todoList=todoList+item}funremoveTodo(item:String){todoList=todoList-item}// ... 其余UI代码和第7课一致}

解析:
inputText是字符串,默认可序列化,直接使用rememberSaveable。
todoList采用不可变List,增删时生成全新集合进行赋值,正常触发重组。
注意:mutableStateListOf直接套rememberSaveable存在兼容隐患,练习场景优先选用不可变列表。

五、本课小结

  1. remember 仅重组保数据,屏幕旋转、页面重建数据丢失。
  2. rememberSaveable 依托安卓实例保存机制,系统重建自动恢复状态。
  3. 存入的数据需要支持序列化,自定义对象需要额外实现Parcelable。
  4. 选型参考:临时界面状态用remember,需要防丢失的数据选用rememberSaveable。

下一课:SideEffect副作用 + LaunchedEffect,处理异步任务和生命周期。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 11:25:37

Redis缓存与数据库一致性实战:方案选型与踩坑总结

1. 缓存命中率上去了&#xff0c;数据却乱了&#xff1a;一致性问题的本质来源我记得第一次在生产环境把Redis缓存铺到订单详情页的时候&#xff0c;效果立竿见影——接口平均耗时从380ms掉到40ms&#xff0c;DB主库的QPS从2万降到3000。正当我沾沾自喜的时候&#xff0c;客服那…

作者头像 李华
网站建设 2026/10/21 5:50:27

RSuite TimeRangePicker 占位符(Placeholder)详解:从用法到源码原理

前端UI组件 【免费下载链接】rsuite &#x1f9f1; A suite of React components . 项目地址&#xff1a; https://gitcode.com/gh_mirrors/rs/rsuite 点击查看 免费下载 导读 本文围绕 RSuite 组件库中 TimeRangePicker 时间区间选择器的 placeholder&#xff08;占位符&am…

作者头像 李华
网站建设 2026/10/22 19:06:33

技术解析|跨境 AI 视频多模型调度架构,如何解决商品崩坏痛点

面向跨境带货场景的多模型融合 AI 视频系统解析 在多模态 AIGC 快速发展的当下&#xff0c;通用视频大模型在艺术创意场景表现亮眼&#xff0c;但落地电商跨境带货投流业务&#xff0c;会遇到一个行业共性难题&#xff1a;商品主体畸变、穿帮、物体逻辑崩坏&#xff0c;大量生成…

作者头像 李华