在AppModule中将Job和协程上下文作为单例移动

时间:2019-05-10 12:10:11

标签: kotlin dagger-2 kotlin-coroutines

我有这段代码,可以在其中指定工作和协程上下文。但是此代码在我拥有的每个ViewModel中不断重复。问题是:

应该将Job()和协程范围作为单例提供,还是在单例之上的模块中提供。对于6个ViewModel都是相同的(包括Dispatchers.IO)。

private val completableJob = Job()
private val coroutineScope = CoroutineScope(Dispatchers.IO + completableJob)

1 个答案:

答案 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

相关问题