为什么viewModelScope.launch默认在主线程上运行

问题描述 投票:0回答:1

虽然我在学习协程,以及如何在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()) }

所以我的第二个问题是,这是要走的路吗?

android multithreading android-architecture-components coroutine
1个回答
1
投票

所以我的第二个问题是,这是走的路吗?

我希望您当前的方法有两件事有所不同。

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())
}

现在您甚至不必担心viewModelScopelaunch等。

© www.soinside.com 2019 - 2024. All rights reserved.