Kotlin Coroutines在Android中的正确方法 [英] Kotlin Coroutines the right way in Android
问题描述
我正在尝试使用异步更新适配器内部的列表,我可以看到模板太多.
I'm trying to update a list inside the adapter using async, I can see there is too much boilerplate.
使用Kotlin协程是否正确?
Is it the right way to use Kotlin Coroutines?
可以进一步优化吗?
fun loadListOfMediaInAsync() = async(CommonPool) {
try {
//Long running task
adapter.listOfMediaItems.addAll(resources.getAllTracks())
runOnUiThread {
adapter.notifyDataSetChanged()
progress.dismiss()
}
} catch (e: Exception) {
e.printStackTrace()
runOnUiThread {progress.dismiss()}
} catch (o: OutOfMemoryError) {
o.printStackTrace()
runOnUiThread {progress.dismiss()}
}
}
推荐答案
在为这个问题苦苦挣扎了几天之后,我认为使用Kotlin进行Android活动的最简单,最清晰的异步等待模式是:
After struggling with this question for days, I think the most simple and clear async-await pattern for Android activities using Kotlin is:
override fun onCreate(savedInstanceState: Bundle?) {
//...
loadDataAsync(); //"Fire-and-forget"
}
fun loadDataAsync() = async(UI) {
try {
//Turn on busy indicator.
val job = async(CommonPool) {
//We're on a background thread here.
//Execute blocking calls, such as retrofit call.execute().body() + caching.
}
job.await();
//We're back on the main thread here.
//Update UI controls such as RecyclerView adapter data.
}
catch (e: Exception) {
}
finally {
//Turn off busy indicator.
}
}
协程的唯一Gradle依赖项是:kotlin-stdlib-jre7
,kotlinx-coroutines-android
.
The only Gradle dependencies for coroutines are: kotlin-stdlib-jre7
, kotlinx-coroutines-android
.
注意:使用job.await()
代替job.join()
,因为await()
会抛出异常,但join()
不会.如果您使用join()
,则在作业完成后需要检查job.isCompletedExceptionally
.
Note: Use job.await()
instead of job.join()
because await()
rethrows exceptions, but join()
does not. If you use join()
you will need to check job.isCompletedExceptionally
after the job completes.
要开始并发改造调用,您可以执行以下操作:
To start concurrent retrofit calls, you can do this:
val jobA = async(CommonPool) { /* Blocking call A */ };
val jobB = async(CommonPool) { /* Blocking call B */ };
jobA.await();
jobB.await();
或者:
val jobs = arrayListOf<Deferred<Unit>>();
jobs += async(CommonPool) { /* Blocking call A */ };
jobs += async(CommonPool) { /* Blocking call B */ };
jobs.forEach { it.await(); };
这篇关于Kotlin Coroutines在Android中的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!