首页 > 解决方案 > Kotlin:覆盖协程的父作业

问题描述

我正在尝试将以下功能迁移到新CoroutineKotlin 1.3

fun launchUI(strategy: CancelStrategy, block: suspend CoroutineScope.() -> Unit): Job {
    return launch(context = UI, parent = strategy.jobs, block = block)
}

但是新GlobalScope.launch函数没有parent参数。文档说:

父作业也继承自 a 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()
    }
}

标签: androidkotlinkotlin-coroutines

解决方案


你的第二个例子是正确的。您可以使用plus将作业添加为新协程的父作业。

fun launchUI(strategy: CancelStrategy, block: suspend CoroutineScope.() -> Unit): Job {
    return GlobalScope.launch(context = Dispatchers.Main + strategy.jobs, block = block)
}

GlobalScope不鼓励使用 of。最好自己创建一个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 { ... }

推荐阅读