API调用和协程问题

时间:2019-05-09 14:59:25

标签: kotlin kotlin-coroutines

我对Kotlin和协程有问题。我已经编写了此方法来调用api并从中获取一些信息。我称呼calculateDistance,它可以为我计算出以KM为单位的距离。我的问题是,在此方法完成之前,UI已加载。我一直在尝试使用协程解决此问题的方法,但是,我似乎陷入了困境。

此函数返回的String然后用于在Activity中呈现。

谢谢

    private fun getPostcodeLocation(listOfPostCodes: List<Pair<Boolean, String>>): String {
        val jsonList = JSONObject()
        jsonList.put("postcodes", JSONArray(listOfPostCodes.map { it.second}))
        val body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonList.toString())
        val request = okhttp3.Request.Builder().url("https://api.postcodes.io/postcodes" ).post(body).build()
        val client = OkHttpClient()
        client.newCall(request).enqueue(object: Callback {
            override fun onResponse(call: Call, response: Response) {
                val responseBody = response.body()?.string()
                val jsonTree = JsonParser().parse(responseBody).asJsonObject
                val resultJsonObj = jsonTree.asJsonObject.getAsJsonArray("result").asJsonArray.iterator()
                resultJsonObj.forEach {
                    val resultObject = Gson().toJsonTree(it).asJsonObject.getAsJsonObject("result")
                    val lat = resultObject.get("latitude").asDouble
                    val lon = resultObject.get("longitude").asDouble
                    listOfLonLat.add(PostcodeLongLat(lon, lat))
                }
                distance =  calculateDistance(listOfLonLat)
                Log.d("PostCodeChecker", "This is the distance inside the callback $distance")
            }

            override fun onFailure(call: Call, e: IOException) {
                println(call)
                println(e)
                Log.d("PostCodeChecker", "Failed to get the information from the API")
                distance = "Not Available"
            }
        })
        Log.d("PostCodeChecker", "This is the distance $distance")
        return distance
    }

期望一个字符串,该字符串表示地图上两个经纬度点之间的距离,为Null。

1 个答案:

答案 0 :(得分:0)

这似乎不是与协程相关的问题。您的api调用是异步发生的,因此您不能指望在返回距离之前就得到结果。您可以做的是在onResponse方法中访问所需的UI元素。例如

override fun onResponse(call: Call, response: Response) {
               //parsing, calculations etc.
                yourTextView.text = distance.toString
            }