虽然我在学习协程,以及如何在Android应用程序中正确使用协程,但我发现我很惊讶。
[使用viewModelScope.launch { }
启动协程并在启动lambda内设置断点时,我发现我的应用程序不再响应,因为它仍在主线程上。
这使我感到困惑,因为viewModelScope.launch { }
的文档明确指出:
启动新的协程而不阻塞当前线程
当前线程不是主线程吗?如果启动默认情况下不在其他线程上运行,则启动的全部目的是什么?
我能够使用viewModelScope.launch(Dispatchers.IO){ }
在另一个线程上运行它,正如我所期望的那样,即在另一个线程上运行。
我想通过launch
方法完成的工作是调用存储库并执行一些IO工作,即调用Web服务并将数据存储在Room db中。所以我想调用viewModelScope.launch(Dispatchers.IO){ }
在不同的线程上完成所有工作,最后更新LiveData结果。
viewModelScope.launch(Dispatchers.IO){
liveData.postValue(someRepository.someWork())
}
所以我的第二个问题是,这是要走的路吗?
所以我的第二个问题是,这是走的路吗?
我希望您当前的方法有两件事有所不同。
1。)第一步将是通过withContext
定义后台操作的调度程序。
class SomeRepository {
suspend fun doWork(): SomeResult = withContext(Dispatchers.IO) {
...
}
}
这样,操作本身就在后台线程上运行,但是您没有将原始作用域强制为“线程外”。
2。] Jetpack Lifecycle KTX提供了liveData {
协程生成器,因此您不必手动将其postValue
附加给它。
val liveData: LiveData<SomeResult> = liveData {
emit(someRepository.someWork())
}
现在您甚至不必担心viewModelScope
和launch
等。