[英]Kotlin: Override parent job of coroutine
我正在嘗試將以下功能遷移到新的Kotlin 1.3
Coroutine
:
fun launchUI(strategy: CancelStrategy, block: suspend CoroutineScope.() -> Unit): Job {
return launch(context = UI, parent = strategy.jobs, block = block)
}
但是新的GlobalScope.launch
函數沒有parent
參數。 文檔說:
父作業也繼承自
CoroutineScope
,但也可以用相應的coroutineContext
元素覆蓋。
但是我不知道該如何替代上級工作。 我現在已經像這樣實現了,但是我不確定它是否可以相同的方式工作:
fun launchUI(strategy: CancelStrategy, block: suspend CoroutineScope.() -> Unit): Job {
val job = GlobalScope.launch(context = Dispatchers.Main, block = block)
strategy.jobs.invokeOnCompletion {
job.cancel()
}
return job
}
誰能幫我?
更新:
class CancelStrategy(owner: LifecycleOwner, val jobs: Job) : LifecycleObserver {
init {
owner.lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
jobs.cancel()
}
}
您的第二個例子是正確的。 您可以使用plus
將該作業添加為新協程的父作業。
fun launchUI(strategy: CancelStrategy, block: suspend CoroutineScope.() -> Unit): Job {
return GlobalScope.launch(context = Dispatchers.Main + strategy.jobs, block = block)
}
但是不鼓勵使用GlobalScope
。 最好創建一個自己的CoroutineScope
。 您的CancelStrategy
看起來不錯。
class CancelStrategy(owner: LifecycleOwner, val jobs: Job) : LifecycleObserver, CoroutineScope {
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + jobs
init {
owner.lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
jobs.cancel()
}
}
現在,您可以像下面這樣啟動協程:
cancelStrategy.launch { ... }
通過將協程的生命周期與某些UI組件對齊,可以將其稱為“結構化並發”。
看看這個文檔: https : //github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md#structured-concurrency-lifecycle-and-coroutine-parent-child-hierarchy
而不是使用GlobalScope
,您應該考慮實現自己的范圍並維護Job
它們,您也可以取消它來取消所有子級。
這是一個簡化的示例:
class Activity : CoroutineScope {
lateinit var job: Job //tied to lifecycle of Activity
fun create() {
job = Job()
}
fun destroy() {
//will cancel all child jobs as well
println("cancel $job and all ${job.children.toList().size} children")
job.cancel()
}
override val coroutineContext: CoroutineContext
get() = Dispatchers.Default + job + CoroutineName("MyActivityContext")
fun doSomething() {
//we launch in the outer scope of Activity
launch {
//...
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.