簡體   English   中英

暫停Kotlin Coroutine不適用於凌空抽射

[英]suspending a kotlin Coroutine does not work with volley

我編寫了以下(測試)函數,通過截擊和協同程序與Google Maps api進行通信。 可悲的是,用suspendCoroutine調用它時,它永遠不會完成。 如果我使用相同的功能,則刪除協程程序內容並實現“正常”回調,則一切正常。 我有點茫然,這里的問題是什么。 有人能幫忙嗎?

代碼將執行到Log.d(LOGTAG,“ AFTERAFTER”),但永遠不會到達Log.d(“ findNaturalLocations”,“ Response:” + response)

suspend fun testNaturalLocations(tag: Tag, lastKnownUserLocation: 
Location): ArrayList<CLDistanceRequest> = suspendCoroutine { 
continuation ->

    Log.d("findNaturalLocations", "getDistanceAndTimeBetweenLocations")

    var distanceRequests = ArrayList<CLDistanceRequest>()

    val mapsBaseUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch/"
    val mapsOutputFormat = "json"

    val location = "location=" + lastKnownUserLocation.latitude.toString() + "," + lastKnownUserLocation.longitude.toString()
    val radius = "radius=5000"
    val keyword = "keyword=Supermarket"
    val name = "name=Supermarket"
    val sensor = "sensor=true"
    val apiKey = "key=API_KEY"

    val finishedUrl = mapsBaseUrl + mapsOutputFormat + "?" + location + "&" + radius + "&" + keyword + "&" + name + "&" + sensor + "&" + apiKey

    Log.d(LOGTAG, finishedUrl)

    val jsObjectRequest = JsonObjectRequest(Request.Method.GET, finishedUrl, null,
            Response.Listener<JSONObject> { response ->
                Log.d("findNaturalLocations", "Response: " + response)

                var results = response.getJSONArray("results")

                // parse distanceRequests, ommitted for brevity

                continuation.resume(distanceRequests)
            },
            Response.ErrorListener { error ->
                Log.e("Error", error.localizedMessage, error)

                continuation.resumeWithException(error)
            }
    )

    Log.d(LOGTAG, "AFTER");

    jsObjectRequest.setShouldCache(false)
    CLGlobal.getRequestQueue().add(jsObjectRequest)

    Log.d(LOGTAG, "AFTERAFTER");
}

用一個簡單的回調做同樣的事情是完美的。

var i = 0;
    runBlocking {
        val query = async(CommonPool) {
            i = this@CLTaskList.test2()
        }

        query.await()
    }

suspend fun test2():Int = suspendCoroutine<Int> { continuation ->
    Log.d("TESTTEST", "TEST2 CALLED")
    test {
        Log.d("TESTTEST", "CONTINUATION")
        continuation.resume(it)
    }
}

fun test(completionHandler: (Int) -> Unit) {
    Log.d("TESTTEST", "TEST CALLED")
    completionHandler(1)
}

正如您在評論中所揭示的,這是運行查詢的方式:

val query = async(CommonPool) { 
    this@CLTaskList.testNaturalLocations(tags[0], 
         CLGlobal.getInstance().mLastKnownLocation!!) 
} 
runBlocking<Unit> { query.await() }

您幾乎已經做好了准備,但是這段代碼全都倒退了:

  1. 您可以讓suspableable函數在線程池中運行,從而減輕某些工作線程在獲得答案之前有阻塞的責任(它不在乎是否被阻塞了)。
  2. 您可以使用runBlocking阻止GUI線程。

在正確的解決方案中,您不需要asyncCommonPoolrunBlocking ,您所需runBlocking就是:

launch(UI) {
    val result = testNaturalLocations(tags[0], 
       CLGlobal.getInstance().mLastKnownLocation!!)
    // deal with the result right here
}

由於testNaturalLocations是一個可testNaturalLocations的函數,因此它不會阻塞您的UI線程,並且當您編寫的回調恢復它時,您的代碼將直接轉到下一行,並分配result

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM