簡體   English   中英

何時以及如何從 Android Activity 調用掛起功能?

[英]When and how to call suspend function from Android Activity?

我有一個調用 POST 請求到服務器的suspend函數。 我想在活動中配置一些文本來顯示我從服務器收到的信息。

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)

我想把這些掛起調用放在哪里(在活動生命周期的哪個部分)? 我應該使用runBlocking以外的其他東西嗎?

默認情況下, runBlocking在調用runBlocking的線程中運行掛起的代碼block

因此,如果您從Activity回調中調用runBlocking ,您的掛起塊將在主線程上執行,您無法從中訪問網絡(查詢服務器)。

您需要在協程塊中為該調用切換調度程序。 最簡單的代碼修復方法是將執行移至Dispatchers.IO

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

話雖如此,我建議兩件事(與您的問題沒有直接關系):

  1. 閱讀Coroutines on Android (本部分和以下部分)

2. 不要在你的情況下使用runBlocking ,而是定義一個正確的job並使用job.launch{}

如果你想在活動中寫:

class MyActivity : AppCompatActivity() {
private val scope = CoroutineScope(newSingleThreadContext("name"))

fun doSomething() {
    scope.launch { ... }
  }
}

暫無
暫無

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

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