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

Android Kotlin环境下如何在Proto DataStore中存储PersistentList

问题原因与解决方案:Proto DataStore存储PersistentList时的序列化异常

异常原因

kotlinx.serialization不支持直接序列化未配置多态规则的接口类型。PersistentList是一个接口,你实际传入的SmallPersistentVector是它的具体实现类,但kotlinx.serialization没有预先注册这个实现类的序列化规则,因此无法识别如何对其进行序列化/反序列化,抛出该异常。

解决方法

方案1:改用普通List替代PersistentList(推荐,最简单)

直接将数据类中的PersistentList替换为标准List,完全避开多态序列化问题:

@Serializable
data class QuizResult(
  val quizNameId: Int,
  val quizAboutId: Int,
  val answers: List<QuestionResult> = emptyList()
)

存储时直接传入现有mutableListOf的结果:

scope.launch {
  context.dataStore.updateData {
    it.copy(
      quizNameId = 123456,
      quizAboutId = 456789,
      answers = results // results是mutableListOf生成的,直接赋值即可
    )
  }
}

方案2:自定义序列化器适配PersistentList

如果必须保留PersistentList,可以通过自定义序列化器,将其转换为普通List进行序列化,反序列化时再转回PersistentList:

  1. 修改数据类,指定自定义序列化器:
@Serializable
data class QuizResult(
  val quizNameId: Int,
  val quizAboutId: Int,
  @Serializable(with = PersistentQuestionResultListSerializer::class)
  val answers: PersistentList<QuestionResult> = persistentListOf()
)
  1. 实现自定义序列化器:
object PersistentQuestionResultListSerializer : KSerializer<PersistentList<QuestionResult>> {
    // 复用List的序列化器,元素类型为QuestionResult
    private val delegateSerializer = ListSerializer(QuestionResult.serializer())

    override val descriptor: SerialDescriptor = delegateSerializer.descriptor

    override fun serialize(encoder: Encoder, value: PersistentList<QuestionResult>) {
        // 序列化时转成普通List
        delegateSerializer.serialize(encoder, value.toList())
    }

    override fun deserialize(decoder: Decoder): PersistentList<QuestionResult> {
        // 反序列化时转回PersistentList
        return delegateSerializer.deserialize(decoder).toPersistentList()
    }
}

这种方式既保留了PersistentList的特性,又解决了序列化问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:18:28