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

如何为动态key的JSON创建适配Retrofit与Jetpack的Data Class

问题原因

你当前的类定义存在不必要的层级封装,这是解析失败的核心原因:
接口返回的data字段本身就是以货币代码为键、汇率为值的JSON对象,而你额外定义的Data类要求Gson在data对象下查找名为hashmapForData的子字段,实际返回结果中不存在该字段,因此解析失败。


正确实现方案

无需单独定义Data类,直接将响应类中的data字段声明为Map类型即可:

// 根响应类
data class CurrencyResponse(
    val query: Query,
    val data: Map<String, Double>
)

// Query字段对应类
data class Query(
    val apikey: String,
    val base_currency: String,
    val timestamp: Long // 建议改为Long类型,避免2038年Int溢出问题
)

数值类型说明

即使部分汇率值为整数格式(如示例中的LTC: 0),Gson也可以正常将其解析为Double类型;如果对汇率精度要求极高,可将Map的值类型改为BigDecimal避免浮点精度丢失。


配合Android Jetpack组件的常用实践

1. 列表展示适配

如果需要在RecyclerView中展示汇率列表,可将Map<String, Double>转换为实体类列表,配合ListAdapter使用:

data class CurrencyRate(
    val code: String,
    val rate: Double
)

// 转换示例
val rateList = currencyResponse.data.map { CurrencyRate(it.key, it.value) }

2. Room持久化适配

如果需要用Room存储响应结果,可添加类型转换器实现Map的持久化:

import androidx.room.TypeConverter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken

class RateConverters {
    @TypeConverter
    fun mapToJson(map: Map<String, Double>): String {
        return Gson().toJson(map)
    }

    @TypeConverter
    fun jsonToMap(json: String): Map<String, Double> {
        val type = object : TypeToken<Map<String, Double>>() {}.type
        return Gson().fromJson(json, type)
    }
}

在Room Database类上添加注解即可生效:

@Database(entities = [YourEntity::class], version = 1)
@TypeConverters(RateConverters::class)
abstract class AppDatabase : RoomDatabase() {
    // 数据库操作Dao定义
}

3. 架构适配

可将Retrofit请求结果包装为Flow或LiveData返回,配合ViewModel实现生命周期感知,符合Jetpack架构规范。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 21:15:04