gpt4 book ai didi

android - 有没有办法重用 Job 实例?

转载 作者:IT老高 更新时间:2023-10-28 13:40:26 25 4
gpt4 key购买 nike

我正在探索在 Android UI 线程上下文中使用协程。我按照 Coroutines Guide UI 中的描述实现了 contextJob .后台工作是从 GUI 开始的,我想在每次点击时重新启动它(停止当前正在运行的并重新启动它)。

但是一个工作一旦被取消就不能被重复使用,所以即使创建一个子工作:

 val job = Job(contextJob)

取消它并没有帮助,因为它必须重新分配。

有没有办法重用 Job 实例?

最佳答案

一个 Job设计的生命周期非常简单。它的“Completed”状态是final,非常类似于Android Activity的“Destroyed”状态。因此,父 Job 最好与 Activity 相关联,如指南中所述。当且仅当 Activity 被破坏时,您应该取消父作业。因为已销毁的 Activity 无法重用,所以您永远不会遇到重用其作业的需要。

建议在每次点击时开始工作的方法是使用参与者,因为它们可以帮助您避免不必要的并发。该指南显示了如何在每次单击时启动它们,但没有显示如何取消当前正在运行的操作。

您将需要一个新的 Job 实例并结合 withContext 使代码块可与其他所有内容分开取消:

fun View.onClick(action: suspend () -> Unit) {
var currentJob: Job? = null // to keep a reference to the currently running job
// launch one actor as a parent of the context job
// actor prevent concurrent execution of multiple actions
val eventActor = actor<Unit>(contextJob + UI, capacity = Channel.CONFLATED) {
for (event in channel) {
currentJob = Job(contextJob) // create a new job for this action
try {
// run an action within its own job
withContext(currentJob!!) { action() }
} catch (e: CancellationException) {
// we expect it to be cancelled and just need to continue
}
}
}
// install a listener to send message to this actor
setOnClickListener {
currentJob?.cancel() // cancel whatever job we were doing now (if any)
eventActor.offer(Unit) // signal to start next action when possible
}
}

actor 始终处于 Activity 状态,直到其父作业(附加到 Activity )被取消。 Actor 等待点击并在每次点击时启动一个action。但是,action 的每次调用都使用 withContext block 包装到其自己的 Job 中,因此可以与其父作业分开取消。

请注意,此代码适用于不可取消的操作或需要一些时间才能取消的操作。当一个 Action 被取消时,它可能需要清理它的资源,并且由于这段代码使用了一个actor,它确保在下一个 Action 开始之前完成前一个 Action 的清理。

关于android - 有没有办法重用 Job 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42829575/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com