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:
- 修改数据类,指定自定义序列化器:
@Serializable data class QuizResult( val quizNameId: Int, val quizAboutId: Int, @Serializable(with = PersistentQuestionResultListSerializer::class) val answers: PersistentList<QuestionResult> = persistentListOf() )
- 实现自定义序列化器:
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
相关产品推荐
相关产品推荐

