在 android kotlin 的同一键上有时处理动态响应对象/数组

Handle dynamic response sometimes object / array on same key on android kotlin

我有来自 this 的 api 的回复,

上有不同
...
"value": [
    {
      "@unit": "C",
      "#text": "28"
    }
  ]

有时

"value":
    {
      "@unit": "C",
      "#text": "28"
    }

我尝试从

创建这个 json 适配器和模型 class
object WeatherResponse {

    open class CuacaResponse{
        @SerializedName("Success")
        val success : Boolean = false
        val row : RowBean? = null
    }

    data class RowBean(
        val data : DataBean? = null
    )

    data class DataBean (
        val forecast : ForecastBean? = null
    )

    data class ForecastBean(
        val area : List<Area>? = null
    )

    data class Area(
        @SerializedName("@id")
        val id :String?="",
        @SerializedName("@description")
        val nama :String?="",
        val parameter : List<DataMain>?=null
        )

    data class DataMain(
        @SerializedName("@description")
        val namaData :String?="",
        @SerializedName("@id")
        val id :String?="",
        @SerializedName("timerange")
        val timeRange : List<TimeRangeItem>
    )

    data class TimeRangeItem(
        // sample data : 202107241800 => 2021-07-24-18:00
        @SerializedName("@datetime")
        val datetime : String,
        @JsonAdapter(ValueClassTypeAdapter::class)
        val value : ArrayList<ValueData>? = null,
    )

    data class ValueData(
        @SerializedName("@unit")
        val unit :String?="",
        @SerializedName("#text")
        val value :String?="",
    )

    class ValueClassTypeAdapter :
        JsonDeserializer<ArrayList<ValueData?>?> {
        override fun deserialize(
            json: JsonElement,
            typeOfT: Type?,
            ctx: JsonDeserializationContext
        ): ArrayList<ValueData?> {
            return getJSONArray(json, ValueData::class.java, ctx)
        }

        private fun <T> getJSONArray(json: JsonElement, type: Type, ctx:
        JsonDeserializationContext): ArrayList<T> {
            val list = ArrayList<T>()
            if (json.isJsonArray) {
                for (e in json.asJsonArray) {
                    list.add(ctx.deserialize<Any>(e, type) as T)
                }
            } else if (json.isJsonObject) {
                list.add(ctx.deserialize<Any>(json, type) as T)
            } else {
                throw RuntimeException("Unexpected JSON type: " + json.javaClass)
            }
            return list
        }
    }
}

我的改造服务:

interface WeatherService {
    @GET("/api/cuaca/DigitalForecast-{province}.xml?format=json")
    suspend fun getWeather(
        @Path("province") provinceName: String? = "JawaTengah"
    ) : WeatherResponse.CuacaResponse?

    companion object {
        private const val URL = "https://cuaca.umkt.ac.id"
        fun client(context: Context): WeatherService {
            val httpClient = OkHttpClient.Builder()
            httpClient.apply {
                addNetworkInterceptor(
                    ChuckerInterceptor(
                        context = context,
                        alwaysReadResponseBody = true
                    )
                )

                addInterceptor { chain ->
                    val req = chain.request()
                        .newBuilder()
                        .build()
                    return@addInterceptor chain.proceed(req)
                }
                cache(null)
            }

            val gsonConverterFactory = GsonConverterFactory.create()

            return Retrofit.Builder()
                .baseUrl(URL)
                .client(httpClient.build())
                .addConverterFactory(gsonConverterFactory)
                .build()
                .create(WeatherService::class.java)
        }
    }
}

但是我从日志请求中得到的结果:

...
{
    "@datetime": "202108070000",
    "value": {
      "size": 4
    }
  },
  {
    "@datetime": "202108070600",
    "value": {
      "size": 4
    }
  },
  {
    "@datetime": "202108071200",
    "value": {
      "size": 4
    }
  }
...

return IDK 的大小,它应该 return 来自 api 的单元和文本数组。 请任何人帮助我解决这个问题,在此先感谢!

最后,我通过将 JsonDeserializer 更改为 TypeAdapterFactory 解决了这个问题,如

中所述