Kotlin-使用GSON和类型泛型(Android)从JSON读取对象列表

问题描述 投票:0回答:1

我有一个名为villagers.json的JSON文件,其格式如下

[
  {
    "name": "Admiral",
    "iconFilename": "brd06.png",
    "houseFilename": "brd06_39_Admiral.png",
    "species": "Bird",
    "gender": "Male",
    "personality": "Cranky",
    "hobby": "Nature",
    "birthday": "01/27",
    "catchphrase": "aye aye",
    "favoriteSong": "Steep Hill",
    "filename": "brd06",
    "uid": "B3RyfNEqwGmcccRC3",
    "colors": [
      "Black",
      "Blue"
    ],
    "styles": [
      "Cool",
      "Cool"
    ]
  },
  { ... },
  etc.
]

以下代码段从Android资产中的JSON文件中读取Villager POJO的列表。

// this works
fun getVillagersFromJSON(context: Context): List<Villager> {
    val jsonFileString = getJsonDataFromAsset(context, "villagers.json")
    return Gson().fromJson(jsonFileString, object : TypeToken<List<Villager>>() {}.type)
}

但是,当尝试使用以下两个函数来泛化POJO的类型时,出现com.google.gson.internal.LinkedTreeMap cannot be cast to Villager错误。

    fun getVillagersFromJSON(context: Context): List<Villager> {
        val jsonFileString = getJsonDataFromAsset(context, "villagers.json")
        jsonFileString?.let { return fromJson(it) }
        return ArrayList()
    }

    // this use of type generics does NOT work
    private inline fun <reified T> fromJson(json: String): List<T> {
        return Gson().fromJson(json, object : TypeToken<List<T>>() {}.type)
    }

使用Kotlin,Gson并键入泛型以从JSON文件读取POJO列表的正确方法是什么?] >>

我有一个名为villagers.json的JSON文件,其格式遵循[{“” :“ Bird”,...

json generics kotlin gson
1个回答
0
投票

虽然我仍在寻找一种不需要明确指定所有类型可能性的更好的解决方案,但是我能够使用泛型的最接近的是以下内容。

    fun getVillagersFromJSON(context: Context): List<Villager> {
         val jsonFileString = getJsonDataFromAsset(context, "villagers.json")
         jsonFileString?.let { return fromJson(it, Villager::class) }
         return ArrayList<Villager>()
    }

    private inline fun <reified T : Any> fromJson(json: String, clazz: KClass<T>): List<T> {
        return when (clazz) {
            Villager::class -> Gson().fromJson(
                json,object : TypeToken<List<Villager>>() {}.type
            ) as List<T>
            // put other cases here
            else -> ArrayList()
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.