So, I had this code running inside a "onBindViewHolder" recycler's adapter method:
launch(UI) {
val bitmapDrawable = loadLargeBitmapDrawable()
imageView.setImageDrawable(bitmapDrawable)
}
This was freezing my app for some seconds, locking my mainthread.
But then I changed to this:
launch { // <- I removed the "UI"
val bitmapDrawable = loadLargeBitmapDrawable()
launch(UI) { //Launch the UI coroutine inside the other
imageView.setImageDrawable(bitmapDrawable)
}
}
Why this is happening? The purpose of coroutines are to make things async inside the same thread (UI) right? Someone can explain me why I had to run a UI coroutine inside another coroutine scope ?
The purpose of coroutines are to make things async inside the same thread (UI) right?
You ascribe more magic to coroutines than there really is. If your loadLargeBitmapDrawable()
function is not suspendable, but simply occupies its thread until done, there is nothing Kotlin can do about it. When you said launch(UI)
, you ordered that function run on the UI thread.
Your second example executes in the CommonPool
context (that's the default) and then posts a task to the UI thread; a more natural way to say it is like this (I use it in my code, with the exact same purpose as you):
launch(UI) {
val bitmapDrawable = withContext(CommonPool) {
loadLargeBitmapDrawable()
}
imageView.setImageDrawable(bitmapDrawable)
}
withContext
will suspend the coroutine you launched on the UI thread, submit the heavyweight operation to the common threadpool, and then resume the coroutine on the UI thread with its result. Now you can push the bitmap to the imageView
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With