我是 Android 开发的新手,我正在尝试使用 OkHttp 和 GSon 从 DarkSky API 获取 json 数据。问题是我需要以某种方式从 onResponse 方法返回响应,但它始终为 null。
这是我的代码:
class DarkSky : Callback {
private var url: String? = null
private var forecast: Forecast? = null
fun fetchJson(lat: Double, long: Double): Forecast? {
this.url = "${Constants.DARK_SKY_BASE_URL}/${Constants.DARK_SKY_KEY}/$lat,$long?exclude=hourly,flags,offset"
val request = Request.Builder().url(url!!).build()
val client = OkHttpClient()
client.newCall(request).enqueue(this)
return this.forecast // when I debug this its NULL
}
override fun onFailure(call: Call, e: IOException) {
println("error")
}
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
val body = response.body()?.string()
val gson = GsonBuilder().create()
val forecast = gson.fromJson(body, Forecast::class.java)
parse(forecast)
}
}
private fun parse(response: Forecast) {
this.forecast = response //when I debug this, it contains data I need.
}
}
编辑:
让它与 BlockingQueue 一起工作。但是不知道。这是个好主意吗?
class DarkSky {
private var url: String? = null
private var forecast: Forecast? = null
fun fetchJson(lat: Double, long: Double): ArrayBlockingQueue<Forecast>? {
this.url = "${Constants.DARK_SKY_BASE_URL}/${Constants.DARK_SKY_KEY}/$lat,$long?exclude=hourly,flags,offset"
val request = Request.Builder().url(url!!).build()
val blockingQueue: ArrayBlockingQueue<Forecast> = ArrayBlockingQueue(1) // <<<
val client = OkHttpClient()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
println("error")
}
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
val body = response.body()?.string()
val gson = GsonBuilder().create()
val forecast = gson.fromJson(body, Forecast::class.java)
blockingQueue.add(forecast) // <<<
}
}
})
return blockingQueue
}
}
不想学习不好的做法。
最佳答案
那是因为
client.newCall(request).enqueue(this)
将在后台线程中异步执行。 因此,当您返回时,它实际上并没有分配值。
解决方案:
您可能需要传递符合特定接口(interface)的类的对象并调用该接口(interface)的方法。
这是您需要做的更改
class DarkSky : CallBack {
private var url: String? = null
private var forecast: Forecast? = null
private var onRequestCompleteListener : OnRequestCompleteListener? =null
fun fetchJson(lat: Double, long: Double,callback : OnRequestCompleteListener) {
this.onRequestCompleteListener = callback
this.url = "${Constants.DARK_SKY_BASE_URL}/${Constants.DARK_SKY_KEY}/$lat,$long?exclude=hourly,flags,offset"
val request = Request.Builder().url(url!!).build()
val client = OkHttpClient()
client.newCall(request).enqueue(this)
}
override fun onFailure(call: Call, e: IOException) {
onRequestCompleteListener?.onError()
println("error")
}
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
val body = response.body()?.string()
val gson = GsonBuilder().create()
val forecast = gson.fromJson(body, Forecast::class.java)
parse(forecast)
}
onRequestCompleteListener?.onSuccess(forecast)
}
private fun parse(response: Forecast) {
this.forecast = response //when I debug this, it contains data I need.
}
}
interface OnRequestCompleteListener{
fun onSuccess(forcast :Forecast)
fun onError()
}
关于Kotlin - OkHttp - 从 onResponse 返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54283464/