android - 在单个作业中执行两个不同的操作

标签 android kotlin-coroutines

我正在尝试在一个作业中使用 Room 执行两个数据库操作,但只有第一个操作正在执行。

在我的 ViewModel 中,我有以下内容:

val supervisorJob = SupervisorJob()
val scope = CoroutineScope(Dispatchers.Main + supervisorJob) 

我有两个数据库操作返回Flow,如下:

第一次操作:

 firstRepo.getSomeData1().collect {
            val size = it.size
            Log.d(TAG, "Size of list is $size")
            it.forEach {
                Log.d(TAG, "Data1 name: ${it.name}")
            }
        }

第二个操作:

secondRepo.getSomeData2().collect {
            val size = it.size
            Log.d(TAG, "Size of list is $size")
            it.forEach {
                Log.d(TAG, "Data2 name: ${it.name}")
            }
        }

我正在尝试按照以下方式执行此操作,它只执行并打印 firstRepo.getSomeData1 并忽略 secondRepo.getSomeData2

我的方法:

fun getAllProtocols() = scope.launch {

    withContext(Dispatchers.IO) {
        firstRepo.getSomeData1().collect {
            val size = it.size
            Log.d(TAG, "Size of list is $size")
            it.forEach {
                Log.d(TAG, "Data1 name: ${it.name}")
            }

        }

        secondRepo.getSomeData2().collect {
            it.forEach {
                Log.d(TAG, "Data2 name: ${it.name}")
            }
        }

    }
}

如果我将每个操作包装在 launch{} 中,那么它们都会被执行。

我不明白为什么会这样?为什么他们不能在同一个工作中执行 还是强制一个作业只能执行一个异步或数据库操作?

最佳答案

同一个协程内的代码是顺序执行的。 流也是顺序的 - collect 函数只是一个常规的挂起函数,仅在收集整个流时(或抛出错误时)才返回。

换句话说,查看您的代码,这意味着第二个流的收集在第一个流完全收集之前无法开始

问题是,第一个流永远不会被完全收集,因为它只是无限期地观察 Room 数据库的变化。

您已经知道如何解决这个问题 - 在单独的协程中启动收集操作以使其并发:

fun getAllProtocols() = scope.launch(Dispatchers.IO) {

    launch {
        firstRepo.getSomeData1().collect {
            val size = it.size
            Log.d(TAG, "Size of list is $size")
            it.forEach {
                Log.d(TAG, "Data1 name: ${it.name}")
            }
        }
    }

    launch {
        secondRepo.getSomeData2().collect {
            it.forEach {
                Log.d(TAG, "Data2 name: ${it.name}")
            }
        }
    }
}

关于android - 在单个作业中执行两个不同的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59700503/

相关文章:

kotlin - 如何从另一个类(在 Kotlin 中)退出 runBlocking 协程?

java - kotlin协程可以像java Timer一样使用吗?

kotlin - Kotlin 中流发出的并行处理值

android - 通过android中的代码解锁屏幕

java - 如何检查服务是否已经在android中运行?

android - 如何在 Windows 8 中禁用 Hyper-V 和安装 HAXM

android - 用作 LaunchedEffect 键时出现 NetworkOnMainThreadException

android - 将 subview 添加到相对布局

java - Android 中的 ByteArray 到 XML 文件

android - Jetpack Compose – LazyColumn 不重组