android - 何时以及如何从 Android Activity 调用挂起函数?

标签 android kotlin kotlin-coroutines

我有一个 suspend 函数调用 POST 请求到服务器。我想在 Activity 中配置一些文本来显示我从服务器收到的信息。

suspend fun retrieveInfo():String 

我尝试在 onCreateonResume 内部调用,但运行时崩溃。

runBlocking { 
    retrieveInfo()
}
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.google.augmentedimage/com.google.AugmentedImageActivity}: android.os.NetworkOnMainThreadException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3086)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3229)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)

我应该将这些暂停调用放在哪里(在 Activity 生命周期的哪个部分)?我应该使用 runBlocking 以外的东西吗?

最佳答案

默认情况下,runBlocking 在调用runBlocking 的线程中运行暂停代码block

因此,如果您从 Activity 回调调用 runBlocking,您的暂停 block 将在主线程上执行,您无法从主线程访问网络(查询服务器)。

您需要在协程 block 中为该调用切换调度程序。最简单的代码修复是将执行移至 Dispatchers.IO

runBlocking {
    withContext(Dispatchers.IO) {
        retrieveInfo()
    }
}

话虽这么说,我建议两件事(与您的问题没有直接关系):

  1. 阅读Coroutines on Android (本部分及后续部分)

<强>2。不要为您的情况使用 runBlocking,而是定义正确的 job 并使用 job.launch{}

关于android - 何时以及如何从 Android Activity 调用挂起函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56912785/

相关文章:

kotlin - 如何在整个项目范围内使用 Kotlin Experimental Time?

android - StateFlow 设置值会丢弃一些事件,但更新不会

java - 如何在 Android 中添加嵌套对象作为 JavascriptInterface?

android - 关于将直播视频流式传输到 android/ios/pc 的建议

android - 使用 LinearLayout 缩放

list - 在 Kotlin 中将 map 转换为 map 列表

android - 类型不匹配。必需 : Nothing Found: Callback<*>

kotlin - 在流的收集中获取当前和以前的值

android - 将多个 Flow<List<T>> 合并为单个 Flow<Map<String, List<T>>>

android - 我们如何在所有设备上测试 Android 应用程序?