解决Ktor多货币汇率数据类序列化VerifyError问题
问题解决方案
1. 解决Rejecting invocation, expected 76 argument registers...错误
该错误源于**ConversionRates数据类字段过多**,导致Kotlinx Serialization生成的反序列化方法超出Android Dalvik虚拟机的寄存器数量限制。直接改用动态Map类型接收汇率数据即可解决:
修改数据类定义
删除ConversionRates类,将Exchange中的对应字段替换为Map<String, Double>:
@Entity(tableName = "exchange") @Serializable data class Exchange( val base_code: String, @Contextual val conversion_rates: Map<String, Double>, val documentation: String, val result: String, val terms_of_use: String, @PrimaryKey val time_last_update_unix: Int, val time_last_update_utc: String, val time_next_update_unix: Int, val time_next_update_utc: String )
适配Room存储(若需持久化)
Room默认不支持Map类型,需添加类型转换器:
class Converters { @TypeConverter fun fromMap(map: Map<String, Double>): String { return Json.encodeToString(map) } @TypeConverter fun toMap(json: String): Map<String, Double> { return Json.decodeFromString(json) } }
在你的RoomDatabase类上添加注解:@TypeConverters(Converters::class)
2. 解决ClassCastException: NetworkRequest$Success cannot be cast to Exchange错误
该错误是因为Repository层错误地将NetworkRequest.Success对象直接包装到RepositoryStatus.Success中,而非提取内部的Exchange数据:
修改Repository层代码
override fun getAllFromApi(mainCurrency: String): Flow<RepositoryStatus> = flow { currencyApi.getCurrencyRate(mainCurrency).collect { networkRequest -> when (networkRequest) { is NetworkRequest.Failure -> emit(RepositoryStatus.Failure(networkRequest.error)) is NetworkRequest.Success<*> -> { val exchangeData = networkRequest.data as Exchange emit(RepositoryStatus.Success(exchangeData)) } } } }.flowOn(Dispatchers.IO)
修正触发错误的代码行
此时it.data直接为Exchange类型,无需额外强转:
_exchangeRates.emit(it.data.conversion_rates.toConversionItem())
额外验证项
- 确认Ktor Client的
ContentNegotiation配置中,Json序列化器已开启ignoreUnknownKeys(你的现有配置已满足),避免API返回的额外字段导致序列化失败。 - 检查API返回的JSON结构,确保
conversion_rates下的键为字符串、值为数字,保证Map<String, Double>可正常反序列化。
内容的提问来源于stack exchange,提问作者Saher Al-Sous
相关产品推荐
相关产品推荐

