Anko协程扩展的正确使用方法是什么?
What is the correct way of using Anko Coroutines extensions?
所以我正在将一个示例应用程序从 RxJava 迁移到 Kotlin/Anko Corountines,我想知道我是否在做最好的(第一种)方法:
fun getPopulationList() {
val ref = asReference()
async(UI) {
try {
ref().setCurrentState(ViewState.State.LOADING)
val background = bg {
repository.populationResponse().execute().body()
}
ref().let {
it.response = background.await()
it.mvpView?.onGetData(it.response)
it.setCurrentState(ViewState.State.FINISH)
}
} catch (e: Exception) {
e.printStackTrace()
ref().mvpView?.onError(e)
}
}
}
我正在使用 MVP 架构,其中我的 Presenter
基础 class 有一个 CompositeSubscription
并且在 onDestroy
的片段或 activity 方法简单取消订阅并清除 CompositeSubscription
对象。但是我想知道 Anko Coroutines 中的 asReference()
函数是否做同样的事情并且不需要保存 Deferred<T>
的列表然后迭代它并一个一个地取消。
顺便说一句,如果我添加一个 Thread.sleep(5000)
来模拟一个大事务并销毁片段,我可以在 logcat 中看到 HTTP 响应,即使片段不是 visible/destroyed 而与RxJava 没有发生,所以我认为我没有正确使用。
更新
fun getPopulationList() {
val ref = asReference()
job = launch(UI) {
try {
ref().setCurrentState(ViewState.LOADING)
val background = bg {
Thread.sleep(5000) //simulate heavy IO
if (isActive) {
repository.populationResponse().execute().body()
} else {
return@bg null
}
}
ref().let {
it.response = background.await()
it.mvpView?.onGetData(it.response)
it.setCurrentState(ViewState.FINISH)
}
} catch (e: Exception) {
RestHttpExceptionHandler().handle(UI, e, ref())
}
}
}
我可以在 onDestroy()
方法中调用 job.cancel()
时取消协程,但要使其正常工作,我必须检查该作业是否处于活动状态并将其转化为 if/else 和一个 return 或不是数据。当作业被取消时,有什么更好的方法来 return 东西吗?
正如您在 asReference() 源代码中看到的那样,它只不过是一个弱引用和调用方法来获取在收集对象时抛出 CancellationException
的引用。它不执行任何取消操作。只是知道收集的对象。
因此您需要保留对 Job 或其子类型的引用才能取消操作。
launch
来自 kotlinx.coroutines returns 作业实例的协程构建器。这是一个例子:
private lateinit var job: Job
private fun startCoroutines() {
val ref = asReference()
job = launch(UI) {
try {
val deferred = async(parent = coroutineContext[Job]) {
//do some work
result//return
}
ref().setData(deferred.await())
} catch (e: Exception) {
e.printStackTrace()
}
}
}
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
备注:
1-当结果类型不重要时,可以使用launch
代替async
。
2- 要在子协程中取消,您必须创建 parent/child 作业层次结构。我通过了 parent(launch
) Job
对 child coroutine(async) 的引用来实现这一点。
3- 因为 取消是合作的 取消实现必须异步完成(参见示例 here)。
3- job.cancel()
用于 onDestroy 取消作业,它是子异步。这可以在 Presenter 中以 MVP 模式完成。
所以我正在将一个示例应用程序从 RxJava 迁移到 Kotlin/Anko Corountines,我想知道我是否在做最好的(第一种)方法:
fun getPopulationList() {
val ref = asReference()
async(UI) {
try {
ref().setCurrentState(ViewState.State.LOADING)
val background = bg {
repository.populationResponse().execute().body()
}
ref().let {
it.response = background.await()
it.mvpView?.onGetData(it.response)
it.setCurrentState(ViewState.State.FINISH)
}
} catch (e: Exception) {
e.printStackTrace()
ref().mvpView?.onError(e)
}
}
}
我正在使用 MVP 架构,其中我的 Presenter
基础 class 有一个 CompositeSubscription
并且在 onDestroy
的片段或 activity 方法简单取消订阅并清除 CompositeSubscription
对象。但是我想知道 Anko Coroutines 中的 asReference()
函数是否做同样的事情并且不需要保存 Deferred<T>
的列表然后迭代它并一个一个地取消。
顺便说一句,如果我添加一个 Thread.sleep(5000)
来模拟一个大事务并销毁片段,我可以在 logcat 中看到 HTTP 响应,即使片段不是 visible/destroyed 而与RxJava 没有发生,所以我认为我没有正确使用。
更新
fun getPopulationList() {
val ref = asReference()
job = launch(UI) {
try {
ref().setCurrentState(ViewState.LOADING)
val background = bg {
Thread.sleep(5000) //simulate heavy IO
if (isActive) {
repository.populationResponse().execute().body()
} else {
return@bg null
}
}
ref().let {
it.response = background.await()
it.mvpView?.onGetData(it.response)
it.setCurrentState(ViewState.FINISH)
}
} catch (e: Exception) {
RestHttpExceptionHandler().handle(UI, e, ref())
}
}
}
我可以在 onDestroy()
方法中调用 job.cancel()
时取消协程,但要使其正常工作,我必须检查该作业是否处于活动状态并将其转化为 if/else 和一个 return 或不是数据。当作业被取消时,有什么更好的方法来 return 东西吗?
正如您在 asReference() 源代码中看到的那样,它只不过是一个弱引用和调用方法来获取在收集对象时抛出 CancellationException
的引用。它不执行任何取消操作。只是知道收集的对象。
因此您需要保留对 Job 或其子类型的引用才能取消操作。
launch
来自 kotlinx.coroutines returns 作业实例的协程构建器。这是一个例子:
private lateinit var job: Job
private fun startCoroutines() {
val ref = asReference()
job = launch(UI) {
try {
val deferred = async(parent = coroutineContext[Job]) {
//do some work
result//return
}
ref().setData(deferred.await())
} catch (e: Exception) {
e.printStackTrace()
}
}
}
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
备注:
1-当结果类型不重要时,可以使用launch
代替async
。
2- 要在子协程中取消,您必须创建 parent/child 作业层次结构。我通过了 parent(launch
) Job
对 child coroutine(async) 的引用来实现这一点。
3- 因为 取消是合作的 取消实现必须异步完成(参见示例 here)。
3- job.cancel()
用于 onDestroy 取消作业,它是子异步。这可以在 Presenter 中以 MVP 模式完成。