簡體   English   中英

為什么這個Kotlin Coroutine會凍結界面?

[英]Why this Kotlin Coroutine is freezing the interface?

所以,我在“onBindViewHolder”回收器的適配器方法中運行了這個代碼:

 launch(UI) {
            val bitmapDrawable = loadLargeBitmapDrawable()          
            imageView.setImageDrawable(bitmapDrawable)
  }

這讓我的應用程序凍結了幾秒鍾,鎖定了我的主線程。

但后來我改為:

launch { // <- I removed the "UI"
            val bitmapDrawable = loadLargeBitmapDrawable()  

            launch(UI) { //Launch the UI coroutine inside the other
                imageView.setImageDrawable(bitmapDrawable)
            }      

  }

為什么會這樣? 協同程序的目的是在同一個線程(UI)中使事物異步嗎? 有人可以解釋為什么我必須在另一個coroutine范圍內運行UI協程?

協同程序的目的是在同一個線程(UI)中使事物異步嗎?

你可以為協同程序賦予更多魔力。 如果你的loadLargeBitmapDrawable()函數不能loadLargeBitmapDrawable() ,但只是占用它的線程直到完成,Kotlin就無法做到這一點。 當你說launch(UI) ,你命令該功能在UI線程上運行。

您的第二個示例是顛倒的,它在CommonPool上下文中執行(這是默認值),然后將任務發布到UI線程; 一個更自然的說法是這樣的(我在我的代碼中使用它,與你的目的完全相同):

launch(UI) {
    val bitmapDrawable = withContext(CommonPool) {
        loadLargeBitmapDrawable() 
    }
    imageView.setImageDrawable(bitmapDrawable)
}

withContext將暫停您在UI線程上啟動的協同程序,將重量級操作提交到公共線程withContext ,然后在UI線程上恢復其結果的協同程序。 現在您可以將位圖推送到imageView

在我的代碼中,我避免使用全局CommonPool上下文,因為它不在我的控制之下,我不知道它在做其他事情有多忙。 相反,我創建自己的線程池作為頂級全局變量:

val threadPool = Executors.newCachedThreadPool().asCoroutineDispatcher()

然后我可以說withContext(threadPool) { ... }並且放心我的線程沒有被任何其他代碼使用,而是我自己的代碼。

暫無
暫無

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

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