
前言上一课学习了 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(modifierModifier.padding(20.dp)){Text(text当前计数$count)Spacer(modifierModifier.height(12.dp))Button(onClick{count}){Text(1)}Spacer(modifierModifier.height(8.dp))Button(onClick{count0}){Text(重置)}}}PreviewComposablefunSaveablePreview(){SaveableDemoPage()}二、逐行代码解读rememberSaveable { mutableIntStateOf(0) }和 remember 用法几乎一模一样唯一区别数据会被序列化保存到Bundle中Activity因配置变更、系统重建的时候可以自动恢复数据。导入路径 androidx.compose.runtime.saveable.rememberSaveableremember 丢失数据的场景旋转屏幕、切换系统深色模式、修改系统字体大小、切换系统语言这些操作都会触发安卓配置变更销毁并且重建Activity。remember仅仅保存在运行时内存当中页面重建之后内存清空状态直接归零。rememberSaveable 底层原理封装安卓原生 onSaveInstanceState 保存机制把状态序列化放进Bundle页面重建之后从Bundle读取数据恢复状态。存在功能限制只能存储可以序列化的数据。整型、字符串、布尔值等基础类型开箱即用自定义实体类需要实现Parcelable或者手动提供Saver保存器。简单区分 rememberSaveable 和 ViewModelrememberSaveable 适合少量UI状态开箱即用代码简短。ViewModel 适合大批量业务数据、跨页面共享数据生命周期更长旋转屏幕不会丢失。ViewModel属于架构进阶内容后续课程再详细讲解。三、核心概念文字对比remember重组的时候可以保留状态屏幕旋转、页面重建数据丢失数据类型没有限制适合页面临时状态。rememberSaveable重组的时候可以保留状态屏幕旋转、页面重建自动恢复数据需要支持序列化适合表单、计数器等需要防丢失的数据。记忆口诀临时状态用remember怕丢数据用rememberSaveable。四、综合练习题填空题能够在旋转屏幕、系统重建时自动保存恢复状态的函数是________。rememberSaveable 底层基于安卓传统的________机制把数据存入Bundle。rememberSaveable 要求保存的数据类型必须是________的自定义类需要实现Parcelable。答案与解析rememberSaveable 解析专门用于跨配置变更、系统重建保存状态。onSaveInstanceState 解析安卓传统保存实例状态机制Compose封装后自动调用。可序列化解析Bundle只能存可序列化数据基础类型默认支持自定义类需Parcelable。判断题remember 和 rememberSaveable 在普通重组时都能保留数据效果一样。答案正确。理由两者在Compose重组时都会保存数据区别只在系统重建场景。用remember保存的计数器旋转屏幕后数值会重置为初始值。答案正确。理由remember只存在内存中Activity销毁重建后内存数据清空。rememberSaveable 可以保存任意类型的数据包括不可序列化的对象。答案错误。理由rememberSaveable基于Bundle存储数据必须可序列化不可序列化对象会运行时报错。简答题什么场景下应该使用rememberSaveable而不是remember举两个实际例子。参考答案当状态需要在系统重建旋转屏幕、语言切换、深色模式切换、内存回收重建后保留时使用。例子1用户在表单页输入了一半内容旋转屏幕后不能清空例子2计数器页面用户点了很多次旋转屏幕后数值要保留。代码实操题把第7课的待办列表示例改造输入文本和待办列表都使用rememberSaveable保存确保旋转屏幕后数据不丢失。写出关键状态定义代码。参考答案ComposablefunTodoListPage(){varinputTextbyrememberSaveable{mutableStateOf()}vartodoListbyrememberSaveable{mutableStateOf(listOfString())}funaddTodo(item:String){todoListtodoListitem}funremoveTodo(item:String){todoListtodoList-item}// ... 其余UI代码和第7课一致}解析inputText是字符串默认可序列化直接使用rememberSaveable。todoList采用不可变List增删时生成全新集合进行赋值正常触发重组。注意mutableStateListOf直接套rememberSaveable存在兼容隐患练习场景优先选用不可变列表。五、本课小结remember 仅重组保数据屏幕旋转、页面重建数据丢失。rememberSaveable 依托安卓实例保存机制系统重建自动恢复状态。存入的数据需要支持序列化自定义对象需要额外实现Parcelable。选型参考临时界面状态用remember需要防丢失的数据选用rememberSaveable。下一课SideEffect副作用 LaunchedEffect处理异步任务和生命周期。