簡體   English   中英

異步執行任務時阻塞Android上的主線程

[英]Blocking the main thread on Android while doing task asynchronously

我一直在努力理解 Android 上多線程與異步編程之間的區別。 主要是為什么需要從主線程中刪除長時間運行的任務,即使該任務是使用協程等異步完成的。

考慮到即使長時間運行的任務可能是異步的,它仍然在 UI 線程上完成工作,這對我來說是有意義的。 因此,即使異步代碼沒有阻塞,重要的是工作而不是阻塞。 這似乎有道理。

但是,也許只是我不知道的語言中的細微差別,但是像 JavaScript 這樣的單線程語言不能將其工作委托給任何其他單獨的線程,它也可以異步工作,但是您可以在 JavaScript 中執行長時間運行的任務異步函數,並且永遠不會出現任何錯誤,表明您在主線程上做了太多工作並從中看到 UI 性能下降。

為什么即使任務被掛起,你仍然需要從 Android 的主線程中刪除代碼,而不是像 javascript 這樣只依賴一個線程的語言?

為什么即使任務掛起你仍然需要從Android的主線程中取出代碼

你沒有。 唯一的規則是

從主線程的事件隊列中取出的任何單個事件都不應該花很長時間來處理。

其中“長”可能是一兩毫秒以上的所有內容。

如果您在事件處理程序中執行阻塞、同步操作,它將計入該事件處理程序執行的持續時間。

如果您在事件處理程序中執行非阻塞的異步操作,處理程序實際上會在啟動操作后立即完成,確保稍后在操作結果准備好時將另一個事件放置在隊列中。

這就是合作與搶占式多線程的本質:在前一種情況下,用戶代碼負責將整個任務分成幾個輕量級事件,而在后一種情況下,無論代碼在做什么,操作系統都會強制執行。 由於整個 GUI 必須在單個線程上運行,搶占式多線程不是一個選項。

所以,具體來說,在 Kotlin 中你可以寫

launch(Dispatchers.Main) {
    val user = makeRestCall("/users/$id")
    usernameText.text = user.name
}

有一些suspend fun makeRestCall(url: String)

暫無
暫無

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

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