Job은 디자인별로 매우 간단한 라이프 사이클을 갖고 있습니다. "완료 됨"상태는 최종이며, 안드로이드 Activity
의 "파괴됨"상태와 매우 유사합니다. 따라서 부모 Job
은 가이드에 설명 된대로 Activity
과 연결하는 것이 가장 좋습니다. 활동이 소멸 된 경우에만 상위 작업을 취소해야합니다. 파괴 된 활동은 재사용 할 수 없기 때문에 작업을 다시 사용할 필요가 없습니다.
불필요한 동시성을 피할 수 있기 때문에 액터를 사용하여 각 클릭에 대한 작업을 시작하는 것이 좋습니다. 가이드는 클릭 할 때마다 시작하는 방법을 보여 주지만 현재 실행중인 작업을 취소하는 방법을 보여주지는 않습니다. 배우가 항상 활성화되어
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
}
}
부모 작업까지 (활동에 부착 :
당신은 다른 모든 것들과는 별도로 코드를 취소 해 블록을 만들기 위해 withContext
와 함께 Job
의 새로운 인스턴스를해야합니다)가 취소됩니다. 배우가 클릭을 기다리고 각 클릭에서 action
을 시작합니다. 그러나 의 각 호출은 withContext
블록을 사용하여 자체 Job
으로 래핑되므로 상위 작업과 별도로 취소 할 수 있습니다.
이 코드는 취소 할 수없는 동작이나 취소하는 데만 시간이 걸립니다. 조치는 취소 될 때 해당 자원을 정리해야 할 수도 있으며,이 코드는 행위자를 사용하므로 다음 조치가 시작되기 전에 이전 조치의 정리가 완료되도록합니다.