使用 Kotlin Coroutine 包装 okhttp3 enqueue() 发生 ClassCastException?

使用 Kotlin 协程包装 enqueue() 时, 总是会发生java.lang.ClassCastException: java.lang.Object cannot be cast to okhttp3.Response 这样的异常. 通过调试也没搞明白原因.

下面是正确的简单用例:

suspendCoroutine<Int> {co -> co.resume(1)} // ok

suspendCoroutine<Int> {co -> co.resumeWithException(NullPointerException())} // ok

下面是发生错误的用例:

val http = OkHttpClient.Builder().build()
    val appid = "mock"
    val secret = "mock"
    val code = "mock"

    val api = "https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${code}&grant_type=authorization_code"
    val request = Request.Builder().get().url(api).build()

    val cc =
            runBlocking {
                val resp = suspendCoroutine<Response> { co ->
                    http.newCall(request).enqueue(object : Callback {
                                override fun onFailure(call: Call, e: IOException) {
                                    co.resumeWithException(e)
                                }

                                override fun onResponse(call: Call, response: Response) {
                                    // 此处 response 是正确的.
                                    co.resume(response)
                                }
                            })
                }

                // Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to okhttp3.Response
                println(resp.body()?.string())

                resp
            }
}
阅读 7.4k
2 个回答

执行了你贴出的部分代码, 没报错, 输出

{"errcode":40013,"errmsg":"invalid appid, hints: [ req_id: FAgFOA0052th44 ]"}

使用

ext.kotlin_version = "1.1.4-2"
kotlinx-coroutines-core:0.18
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进