You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin调用async报suspension functions can be called only within coroutine body问题咨询

错误原因
  1. 你参考的旧教程适配的是早期Kotlin协程版本,早期协程库提供顶层async函数,新版协程库已移除该API,所有协程构造器(launch/async等)都必须通过CoroutineScope调用,这是报错的直接诱因
  2. handleLoadWebView本身就是挂起函数,内部使用runBlocking属于严重的反模式:runBlocking会阻塞当前线程,在Android主线程调用大概率会触发ANR,完全违背协程非阻塞的设计理念
  3. 你当前写的async { getTokenAsync() }.await()属于冗余写法,等价于直接调用getTokenAsync(),没有任何并发收益
解决方案

最优方案(推荐)

直接删除多余的runBlocking和async逻辑,直接调用挂起函数即可:

private suspend fun handleLoadWebView() {
    //some code here.....

    val token = getTokenAsync()
    val jsonResp = JSONObject(token)
    loadWebView(exampleActivity, jsonResp.getString("access_token"), subdomain, content, options)
}

需保留async并发的场景(比如后续要同时执行多个挂起任务)

使用coroutineScope替代runBlocking,它是挂起函数不会阻塞线程,且自带协程作用域:

private suspend fun handleLoadWebView() = coroutineScope {
    //some code here.....

    // 此处作用域内可正常调用async
    val resp = async { getTokenAsync() }
    val token = resp.await()
    val jsonResp = JSONObject(token)
    loadWebView(exampleActivity, jsonResp.getString("access_token"), subdomain, content, options)
}

如果一定要保留原有runBlocking写法(极不推荐),手动指定作用域调用async即可解决报错:

runBlocking{
    // 手动指定当前runBlocking的作用域调用async
    val resp = this.async { getTokenAsync() }
    token = resp.await()
    val jsonResp = JSONObject(token)
    loadWebView(exampleActivity, jsonResp.getString("access_token"), subdomain, content, options)
}

内容的提问来源于stack exchange,提问作者Cristobal BL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 02:15:02