如何在 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
接口并让它观察Lifecycle
个 Activity/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
会在ViewModel
或Activity / Fragment
被销毁后自动取消,所以你不用担心它们:
viewModelScope.launch {
myLibrayObject.doWork() //<- suspend function, you decide the thread inside this function
}
如何在与 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
接口并让它观察Lifecycle
个 Activity/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
会在ViewModel
或Activity / Fragment
被销毁后自动取消,所以你不用担心它们:
viewModelScope.launch {
myLibrayObject.doWork() //<- suspend function, you decide the thread inside this function
}