Комментарии 3
Мне кажется пример не самый удачный. Блюрить картинку вы ещё должны до того как она попадёт в адаптер в главный поток. И обычно это типичный подход, так делают(трансформации, блюры и тд) наверное почти все загрузчики картинок.
Да и вообще, чем вам не нравится «дедовский» способ?
В принципе, подход имеет право на жизнь, но я бы изменил несколько моментов:
- Зачем backgroundTask знать о scope? Это похоже на нарушение инкапсуляции.
- В блоке result было бы неплохо сразу иметь доступ ко View
- isActive не будет работать, как задумывается. Вы делаете await уже после проверки isActive, соответственно, если корутина успела хотя бы запустится, проверка будет бесполезна.
- Зачем запускать job в главном потоке?
Я бы сделал как-то так:
inline fun <T, reified R : View> R.doAsync(
crossinline backgroundTask: suspend () -> T?,
crossinline onResult: R.(T?) -> Unit
) {
val job = CoroutineScope(Dispatchers.Default)
val attachListener = object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(p0: View?) {}
override fun onViewDetachedFromWindow(p0: View?) {
job.cancel()
}
}
addOnAttachStateChangeListener(attachListener)
job.launch {
val data = try {
backgroundTask()
} catch (e: Exception) {
e.printStackTrace()
null
}
if (isActive) {
try {
withContext(Dispatchers.Main) { onResult(data) }
} catch (e: Exception) {
e.printStackTrace()
}
}
removeOnAttachStateChangeListener(attachListener)
}
}
Использовать будет проще:
textView.doAsync({
doSomeHeavyTask()
"some text"
}) { text = it }
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Работaем с View асинхронно с использованием корутин