自定义Country数据类存入rememberSaveable后旋转设备崩溃求助
解决rememberSaveable存储自定义Country对象旋转崩溃问题
核心原因
rememberSaveable 默认仅支持保存**可序列化(Serializable)或可Parcel化(Parcelable)**的对象,自定义Country数据类如果未实现这两个接口之一,或者自定义Saver逻辑存在漏洞,就会在设备旋转(配置变更)时因无法恢复对象而崩溃。
解决方案
方案1:让Country实现Parcelable(推荐)
Parcelable是Android原生的高效序列化方式,步骤如下:
- 在模块的
build.gradle.kts中添加Parcelize插件:
plugins { id("com.android.application") id("org.jetbrains.kotlin.android") id("kotlin-parcelize") // 新增该插件 }
- 修改
Country数据类,添加@Parcelize注解并实现Parcelable:
import android.os.Parcelable import kotlinx.parcelize.Parcelize @Parcelize data class Country( val name: String, val cc: String, val flag: String // 若flag是资源ID则用Int,Bitmap需转ByteArray处理 ) : Parcelable
- 直接使用
rememberSaveable无需额外配置:
val initCountry = Country("China", "CN", "🇨🇳") var state by rememberSaveable { mutableStateOf<Country?>(initCountry) }
方案2:手动实现Saver(适用于无法实现Parcelable的场景)
如果Country包含非可Parcel化的属性,可自定义Saver手动处理对象的保存与恢复:
// 定义自定义Saver val countrySaver = Saver<Country?, Bundle>( save = { country -> country?.let { bundleOf( "name" to it.name, "cc" to it.cc, "flag" to it.flag ) } ?: Bundle() }, restore = { bundle -> if (bundle.isEmpty) null else { Country( bundle.getString("name") ?: "", bundle.getString("cc") ?: "", bundle.getString("flag") ?: "" ) } } ) // 使用自定义Saver初始化状态 val initCountry = Country("China", "CN", "🇨🇳") var state by rememberSaveable(saver = countrySaver) { mutableStateOf<Country?>(initCountry) }
排查注意事项
- 检查
Country的所有属性是否都可序列化:若包含Context、Drawable等非序列化对象,需转换为可保存的类型(比如资源ID、文件路径)。 - 自定义
Saver时,确保保存和恢复的键名完全一致,且处理了null场景。 - 若使用
Serializable,注意其性能低于Parcelable,且某些复杂对象可能序列化失败。
内容的提问来源于stack exchange,提问作者Prabh
相关产品推荐
相关产品推荐

