我有这段代码,可以在其中指定工作和协程上下文。但是此代码在我拥有的每个ViewModel
中不断重复。问题是:
应该将Job()和协程范围作为单例提供,还是在单例之上的模块中提供。对于6个ViewModel都是相同的(包括Dispatchers.IO)。
private val completableJob = Job()
private val coroutineScope = CoroutineScope(Dispatchers.IO + completableJob)
答案 0 :(得分:0)
在Kotlin中,所有协程都在CoroutineScope内运行。范围 通过其工作来控制协程的寿命。取消时 作用域的工作,它将取消在该作用域中启动的所有协程。 在Android上,您可以在以下情况下使用范围取消所有正在运行的协程, 例如,用户导航离开“活动”或“片段”。 范围还允许您指定默认调度程序。调度员 控制哪个线程运行协程。
如果您打算从数据库中检索某些数据只是为了更新UI,而用户突然退出了您的活动,那么使协程保持活动的意义何在?
这就是通常在这样的viewmodel onCleared()
方法中取消协程的原因:
override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}
要减少样板代码,可以使用该库:
dependencies {
...
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:x.x.x"
}
该库将viewModelScope添加为 ViewModel类。此范围绑定到Dispatchers.Main并将 清除ViewModel后自动取消。代替 不必在每个ViewModel中创建一个新的作用域,您可以使用 viewModelScope和库将负责设置和 清除您的范围。
class MainViewModel : ViewModel() {
// Make a network request without blocking the UI thread
private fun makeNetworkRequest() {
// launch a coroutine in viewModelScope
viewModelScope.launch(Dispatchers.IO) {
// slowFetch()
}
}
// No need to override onCleared()
}
但是,如reem.halamish
所指出只要有什么工作要做(例如,插入数据库),我们就会使用GlobalScope.launch {...}使协程在应用程序运行之前就可以生存。
来源和更多信息:https://codelabs.developers.google.com/codelabs/kotlin-coroutines/#4