You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中用kotlinx.serialization序列化含SnapshotStateList的类失败怎么办

解决SnapshotStateList序列化异常方案

问题原因

kotlinx.serialization默认未提供SnapshotStateList的内置序列化器,即使该类是List的子类,序列化框架也不会自动匹配普通List的序列化器,因此会抛出找不到序列化器的错误。

方案1:单属性指定序列化器(无需全局配置)

直接给SnapshotStateList类型的属性加@Serializable注解,指定使用ListSerializer作为序列化器即可,示例代码如下:

import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.ListSerializer

@Serializable
data class ListContainer(
    // 若列表存储自定义类型,将String::class.serializer()替换为对应类型的序列化器
    @Serializable(with = ListSerializer::class)
    val dataList: SnapshotStateList<String>
)

方案2:全局注册序列化器(无需逐个属性加注解)

如果项目中多处使用SnapshotStateList作为属性类型,可以统一注册序列化规则,避免重复加注解:

  1. 构建序列化模块,绑定SnapshotStateList与对应序列化规则
import kotlinx.serialization.modules.SerializersModule
import androidx.compose.runtime.snapshots.SnapshotStateList
import kotlinx.serialization.builtins.ListSerializer

val composeSerializersModule = SerializersModule {
    contextual(SnapshotStateList::class) { typeArgs ->
        ListSerializer(typeArgs[0])
    }
}
  1. 初始化Json序列化工具时传入该模块
import kotlinx.serialization.json.Json

val json = Json {
    serializersModule = composeSerializersModule
}

完成配置后,实体类无需额外添加属性级注解即可正常序列化:

@Serializable
data class ListContainer(
    val dataList: SnapshotStateList<String>
)

可选优化:反序列化直接生成SnapshotStateList

上述两种方案默认反序列化后得到普通ArrayList,如果需要反序列化后直接拿到SnapshotStateList,可以自定义专用序列化器:

import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.builtins.ListSerializer
import androidx.compose.runtime.toMutableStateList

class SnapshotStateListSerializer<T>(
    elementSerializer: KSerializer<T>
) : KSerializer<SnapshotStateList<T>> {
    private val delegate = ListSerializer(elementSerializer)
    override val descriptor: SerialDescriptor = delegate.descriptor

    override fun serialize(encoder: Encoder, value: SnapshotStateList<T>) {
        delegate.serialize(encoder, value)
    }

    override fun deserialize(decoder: Decoder): SnapshotStateList<T> {
        return delegate.deserialize(decoder).toMutableStateList()
    }
}

使用时替换之前的ListSerializer即可,也可以直接注册到全局序列化模块中。


内容的提问来源于stack exchange,提问作者Waqas Tahir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 07:36:04