有一个代码:
class ApiDataSourceIMPL(private val exchangeRateDataSource: ExchangeRateDataSource):
ApiDataSource {
override fun startMigration (context: Context) {
val call = ApiClient.instance?.api?.loadExchangeRateApi()
call?.enqueue(object: Callback<ArrayList<ExchangeRateApiModel>> {
override fun onResponse(
call: Call<ArrayList<ExchangeRateApiModel>>,
response: Response<ArrayList<ExchangeRateApiModel>>
) {
// создаём список
var loadExchangeRate: ArrayList<ExchangeRateApiModel>? = null
// очищаем массив
loadExchangeRate?.clear()
// получаем данные с сервера
loadExchangeRate = (response.body() as ArrayList<ExchangeRateApiModel>?)!!
// помещение данных в локальную базу данных
for (audit in loadExchangeRate) {
// audit.id = 1
audit.id?.let {
ExchangeRateModel(
it,
audit.AUD.toString(),
audit.EUR.toString(),
audit.JPY.toString(),
audit.MDL.toString(),
audit.RUB.toString(),
)
}?.let {
exchangeRateDataSource.insert(
it
)
}
}
Toast.makeText(context, "ЗАГРУЗКА", Toast.LENGTH_SHORT).show()
}
override fun onFailure(call: Call<ArrayList<ExchangeRateApiModel>>, t: Throwable) {
Toast.makeText(context, "ОШИБКА! ВКЛЮЧИТЕ ИНТЕРНЕТ!", Toast.LENGTH_SHORT).show()
}
})
}
}
执行后,Toast 弹出ОШИБКА! ВКЛЮЧИТЕ ИНТЕРНЕТ!
,尝试调试,仅到达行call?.enqueue(object: Callback<ArrayList<ExchangeRateApiModel>>
(独占),然后转到“紧急”消息
请告诉我可能是什么原因造成的以及如何解决它。
ApiClient 代码:
class ApiClient private constructor() {
val api: ApiInterface
get() = retrofit!!.create(
ApiInterface::class.java)
init {
retrofit =
Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create())
.build()
}
companion object {
private val BASE_URL = "https://api.apilayer.com/"
private var apiClient: ApiClient? = null
private var retrofit: Retrofit? = null
val instance: ApiClient?
@Synchronized get() {
if (apiClient == null) {
apiClient =
ApiClient()
}
return apiClient
}
}
}
获取请求:
@Headers("apikey: мой ключ")
@GET("exchangerates_data/latest?symbols=AUD%2CEUR%2CJPY%2CMDL%2CRUB&base=USD")
fun loadExchangeRateApi(): Call<ArrayList<ExchangeRateApiModel>>
包括互联网
<uses-permission android:name="android.permission.INTERNET" />
在清单中是
甚至发送请求(在这个 api 中,每个月的请求数量是有限的,并且在应用程序启动后,计数器每次都会增加)
使用Log.e("ApiDataSource", "onFailure", t)
得到:
2022-08-23 20:29:16.392 21052-21052/com.sem.exchangerate E/ApiDataSource: onFailure
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:80)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:40)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:153)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
json:
{
"base": "USD",
"date": "2022-08-23",
"rates": {
"AUD": 1.444127,
"EUR": 1.00345,
"JPY": 136.770153,
"MDL": 19.351829,
"RUB": 60.249987
},
"success": true,
"timestamp": 1661277305
}
接收型号:
data class ExchangeRateApiModel (
@SerializedName("id") @Expose
var id: Int? = 1,
@SerializedName("AUD") @Expose
val AUD: Double? = null,
@SerializedName("EUR") @Expose
val EUR: Double? = null,
@SerializedName("JPY") @Expose
val JPY: Double? = null,
@SerializedName("MDL") @Expose
val MDL: Double? = null,
@SerializedName("RUB") @Expose
val RUB: Double? = null
)
写入数据库的模型:
@Entity(tableName = "exchange_rate_table")
class ExchangeRateModel(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id:Int,
@ColumnInfo(name = "AUD")
val AUD: String,
@ColumnInfo(name = "EUR")
val EUR: String,
@ColumnInfo(name = "JPY")
val JPY: String,
@ColumnInfo(name = "MDL")
val MDL: String,
@ColumnInfo(name = "RUB")
val RUB: String
)
// 我试图只获取货币值
你不能马上得到一个嵌套对象——你需要一个所有 json 的模型,并且在接收到它之后,从中取出你需要的一切。
您需要另一个视图类:
到处都可以
ArrayList<ExchangeRateApiModel>
用这个新的类来代替。