[英]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.