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

如何让Room TypeConverter返回正确对象而非LinkedTreeMap?

问题描述

我定义了如下实体类:

@Entity
data class ListResponse(
    @SerializedName("answer")
    @ColumnInfo(name = "answer")
    val answer: Map<Int, ItemList>
)
 
data class ItemList(
    @SerializedName("yes")
    val yes: YesItem,
 
    @SerializedName("no")
    val no: NoItem
)
 
data class YesItem(
    @SerializedName("time")
    val timeYes: String,
 
    @SerializedName("date")
    val dateYes: String
)
 
data class NoItem(
    @SerializedName("time")
    val timeNo: String,
 
    @SerializedName("date")
    val dateNo: String
)

对应的TypeConverter:

@TypeConverter
fun convertFromMapToJSONString(map: Map<Int, ItemList>): String {
    return Gson().toJson(promotionMap)
}

@TypeConverter
fun convertFromJSONStringToMap(jsonString: String?): Map<Int, ItemList>? {
    return Gson().fromJson<Map<Int, ItemList>>(jsonString, MutableMap::class.java)
}

Repository和Dao代码:

// Repository部分代码
suspend fun insert(respone: ListResponse) {
    dao.insert(respone)
}

suspend fun getAll(): ListResponse {
    return dao.getAll()
}
@Dao
interface ListDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(list: ListResponse): Long

    @Query("SELECT * FROM $TABLE_NAME")
    suspend fun getAll(): ListResponse

    companion object {
        const val TABLE_NAME = "list_table"
    }
}

目前遇到的问题:liveData.getValue()返回的是LinkedTreeMap而非ListResponse对象,但手动执行以下转换能得到正确的ListResponse:

JsonObject jsonObject = new Gson().toJsonTree(liveData.getValue()).getAsJsonObject();
ListResponse reedUnreadItemList = new Gson().fromJson(jsonObject, ListResponse.class);

想把这个转换逻辑整合到TypeConverter里,让liveData.getValue()直接返回正确的ListResponse对象。


解决方案

问题根源是TypeConverter的反序列化逻辑未指定泛型类型,Gson只能把Map的value解析成默认的LinkedTreeMap,导致整个ListResponse的类型异常。直接修改TypeConverter即可解决:

  • 修正序列化方法的笔误
    原来的convertFromMapToJSONString里误用了未定义的promotionMap,替换成参数map:
@TypeConverter
fun convertFromMapToJSONString(map: Map<Int, ItemList>): String {
    return Gson().toJson(map)
}
  • 修改反序列化方法,明确泛型类型
    放弃使用MutableMap::class.java,改用TypeToken让Gson识别Map<Int, ItemList>的具体类型:
@TypeConverter
fun convertFromJSONStringToMap(jsonString: String?): Map<Int, ItemList>? {
    val targetType = object : TypeToken<Map<Int, ItemList>>() {}.type
    return Gson().fromJson(jsonString, targetType)
}
  • 确认Room关联TypeConverter
    在你的RoomDatabase类上加上@TypeConverters注解,引入这个转换器类:
@Database(entities = [ListResponse::class], version = 1)
@TypeConverters(YourConverterClass::class) // 替换成你的转换器类名
abstract class AppDatabase : RoomDatabase() {
    abstract fun listDao(): ListDao
}

修改完成后,Room读取数据时会正确解析answer字段的Map结构,liveData.getValue()就能直接返回正确的ListResponse对象,无需再手动转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:45:30