如何在 Kotlin 库中使用协程

How to use coroutines in a Kotlin Library

如何在与 activity 生命周期无关的库 class 中正确使用协程?

现在,我在我的 class 中创建了一个私人 属性:

private val coroutineScope = CoroutineScope(Dispatchers.Main)

并有一个取消方法,用于取消作用域。

 public fun cancel() {
        coroutineScope.coroutineContext.cancelChildren()
 }

有没有更简洁的方法来完成这项工作,而不必在 onPause/OnStop 中对我的库 class 调用取消?

编辑:

此外,还有一个问题:如果我创建的 CoroutineContext 在单例中,这有关系吗?像这样:

public object MyObject {
   
    private val coroutineScope = CoroutineScope(Dispatchers.Main)
}

是否存在内存泄漏或类似的危险?

简单地说不,你在需要的时候创建一个范围,当你不再需要它的时候就取消它。 Scope 负责所有协程的生命周期 从中解雇。协程是可暂停计算的一个实例。一旦您不再需要该计算,就可以取消它,以便在真正需要的地方节省计算能力。为了避免通过他们的工作跟踪所有被解雇的协程,我们有一个范围。想象一下,有 1000 个独立协程并且必须跟踪 1000 个作业才能取消它们,而不是那样,我们有一个范围可以一次取消它们。您可以简单地调用 scope.cancel().

避免在 onPause/onStop 中手动调用 cancel() 的一种方法是使用观察模式,让你的库 class 实现 LifecycleObserver 接口并让它观察LifecycleActivity/Fragment 感兴趣。

Singleton 只是 class 的一个曾经存在的实例,没有理由在其中包含 CoroutineScope 个实例会出现任何问题。

how do i correctly use coroutines in a Library class which has nothing to do with the activity lifecycle?

好吧,我建议您不要在库 class 中创建 coroutineScope,而是通过指定哪个线程将 class 函数转换为 suspend 函数(Dispatcher) 它应该 运行 on:

suspend fun doWork() {
    withContext(Dispatchers.IO) {    //run on IO thread
        //do your stuff
    }
}

然后, 使用内置 coroutineScope,例如 ViewModel 中的 viewModelScope,或 [=19 中的 lifecycleScope =] 来执行这个 suspend 函数。那些内置的coroutineScopes会在ViewModelActivity / Fragment被销毁后自动取消,所以你不用担心它们:

viewModelScope.launch {
    myLibrayObject.doWork()    //<- suspend function, you decide the thread inside this function
}