我很难理解如何用莫希转换JSON数据。我正在学习Android和Kotlin,我的应用程序应该加载和显示COVID数据。输入的JSON格式如下:
[
{
"infected": 109782,
"tested": "NA",
"recovered": 75243,
"deceased": 2926,
"country": "Algeria",
"moreData": "https://api.apify.com/v2/key-value-stores/pp4Wo2slUJ78ZnaAi/records/LATEST?disableRedirect=true",
"historyData": "https://api.apify.com/v2/datasets/hi0DJXpcyzDwtg2Fm/items?format=json&clean=1",
"sourceUrl": "https://www.worldometers.info/coronavirus/",
"lastUpdatedApify": "2021-02-11T12:15:00.000Z"
},
{
"infected": 425561,
"tested": 11205451,
"recovered": 407155,
"deceased": 8138,
"country": "Austria",
"moreData": "https://api.apify.com/v2/key-value-stores/RJtyHLXtCepb4aYxB/records/LATEST?disableRedirect=true",
"historyData": "https://api.apify.com/v2/datasets/EFWZ2Q5JAtC6QDSwV/items?format=json&clean=1",
"sourceUrl": "https://www.sozialministerium.at/Informationen-zum-Coronavirus/Neuartiges-Coronavirus-(2019-nCov).html",
"lastUpdatedApify": "2021-02-11T12:15:00.000Z"
},
...
]
正如你所看到的,数字也可以用字符串来表示(如“tested”),而且一些国家的URL可能会丢失,所以我按照莫希文档创建了2个数据类和一个自定义适配器。
//desired structure
data class CountryData(
val infected: Int,
val tested: Int,
val recovered: Int,
val deceased: Int,
val country: String,
val moreData: String,
val historyData: String,
val sourceUrl: String,
val lastUpdatedApify: String
)
//actual JSON
data class CountryDataJson(
val infected: String,
val tested: String,
val recovered: String,
val deceased: String,
val country: String,
val moreData: String?,
val historyData: String?,
val sourceUrl: String?,
val lastUpdatedApify: String
)
自定义适配器:
import android.util.Log
import com.example.coronastats.network.CountryData
import com.example.coronastats.network.CountryDataJson
import com.squareup.moshi.FromJson
class CountryJsonAdapter {
@FromJson fun fromJson(countryDataJson: CountryDataJson): CountryData {
val countryData = CountryData(
if (countryDataJson.infected != "NA") countryDataJson.infected.toInt() else -1,
if (countryDataJson.tested != "NA") countryDataJson.tested.toInt() else -1,
if (countryDataJson.recovered != "NA") countryDataJson.recovered.toInt() else -1,
if (countryDataJson.deceased != "NA") countryDataJson.deceased.toInt() else -1,
countryDataJson.country,
countryDataJson.moreData ?: "NA",
countryDataJson.historyData ?: "NA",
countryDataJson.sourceUrl ?: "NA",
countryDataJson.lastUpdatedApify
)
Log.d("adapterLOG", "fromJson triggered")
return countryData
}
}
我的服务API:
import com.example.coronastats.CountryJsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.GET
private const val BASE_URL = "https://api.apify.com/"
private val moshi = Moshi.Builder()
.add(CountryJsonAdapter())
.build()
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(BASE_URL)
.build()
interface CoronaApiService {
@GET("v2/key-value-stores/tVaYRsPHLjNdNBu7S/records/LATEST?disableRedirect=true")
suspend fun getStatistics() : List<CountryData>
}
object CoronaApi {
val retrofitService: CoronaApiService by lazy {
retrofit.create(CoronaApiService::class.java)
}
}
结果我得到了一个空的屏幕,适配器中的日志从来没有被触发过,所以我假设出了什么问题,我的适配器从来没有被调用过。
NB:如果没有这些转换器的东西,应用程序可以使用标准的KotlinJsonAdapterFactory()和CountryData类作为所有字符串运行,但我想知道如何获得这里的结构。
1条答案
按热度按时间goqiplq21#
我认为
CountryDataJson
缺少默认值。阅读文档时,我注意到以下问题:在Kotlin中,如果这些字段位于主构造函数中,则它们必须具有默认值。