Я пытаюсь прочитать следующие данные из API:
[
[
1724180400000,
"59191.45000000",
"59597.28000000",
"59137.78000000",
"59511.99000000",
"544.56764000",
1724183999999,
"32351755.73378980",
51002,
"290.20494000",
"17241827.16012430",
"0"
],
[
1724184000000,
"59512.00000000",
"59722.72000000",
"59421.38000000",
"59589.07000000",
"301.58055000",
1724187599999,
"17968010.37382020",
23563,
"169.48375000",
"10099057.30721750",
"0"
]
]
Но Retrofit ожидает, что ответ JSON будет начинаться с «{» вместо «[».
Я попробовал сериализовать данные со следующими зависимостями:
implementation(libs.retrofit)
implementation(libs.retrofit2.kotlinx.serialization.converter)
implementation(libs.okhttp)
implementation(libs.kotlinx.serialization.json)
Когда я говорю Retrofit ожидать список со списками, он сообщает, что «Сериализатор для класса «Любой» не найден». Как сериализовать этот тип ответа только с помощью массивов, содержащих смешанные типы (String и Int)?
Если тип не имеет значения, вы можете просто использовать тип String
.
@GET("test")
fun test(): Call<List<List<String>>>
Если тип имеет значение, вы можете использовать JsonPrimitive
.
@GET("test")
fun test(): Call<List<List<JsonPrimitive>>>
После того, как вы получили данные, вы можете проанализировать их List<List<Any>>
вот так.
val result: List<List<JsonPrimitive>> = response.body()!!
val parsedResult: List<List<Any>> = result.map { innerItem ->
innerItem.map {
if (it.isNumber) it.asInt
else it.asString
}
}
println(parsedResult)
Ответы в этой теме очень помогли понять и решить проблему. В своем приложении для Android я реализовал такое решение:
В сервисе API (интерфейс Retrofit 2)
@GET("klines.json")
suspend fun getKlines(): List<List<JsonPrimitive>>
В сетевом репозитории извлеките и преобразуйте rawJson в мой собственный класс Kline.
override suspend fun getKlines(): List<Kline> {
val rawJson = apiService.getKlines()
return rawJson.map { data ->
Kline(
timestamp = data[0].long,
open = data[1].double,
high = data[2].double,
low = data[3].double,
close = data[4].double,
volume = data[5].double,
closeTime = data[6].long,
quoteAssetVolume = data[7].double,
numberOfTrades = data[8].int,
takerBuyBaseAssetVolume = data[9].double,
takerBuyQuoteAssetVolume = data[10].double
)
}
}
Тип Call
в моем сценарии не понадобился, поскольку функции вызываются из области сопрограммы.
Результат rawJson в logcat:
[[1724151600000, "60716.01000000", "60734.91000000", "60401.90000000", "60518.82000000", "1086.55870000", 1724155199999, "65807817.60717790", 58639, "538.35193000", "32602791.90598670", "0"], [...] ]
Эта реализация работает для меня, но приветствуются лучшие решения!