ViewModel 中的 Kotlin Flow 有时不会从 Room table 发出数据

Kotlin Flow in ViewModel doesn't emit data from Room table sometimes

我试图在我的 ViewModel 中组合三个不同的流来制作一个项目列表,然后将其显示在片段中的 RecyclerView 上。我发现当导航到屏幕时,当 table 中还没有数据时,testData1 的流不会发出 table 中的数据。大概有 1/5 的时间发生。我认为这是一个时间问题,因为它经常发生,但我不太明白为什么会发生。此外,这仅在我合并流时发生,所以也许我在一个 ViewModel 中只能有这么多流?

我添加了一些代码来检查 setListData() 期间数据是否在 table 中,它确实存在。我也可以看到发射正在发生,但是没有来自房间的数据。任何指导将不胜感激!

我使用的版本:

科特林:1.4.20-RC
房间:2.3.0-alpha03

这是我的 ViewModel

class DemoViewModel @Inject constructor(
        demoService: DemoService,
        private val demoRepository: DemoRepository
) : ViewModel() {

    private val _testData1 = demoRepository.getData1AsFlow()
    private val _testData2 = demoRepository.getData2AsFlow()
    private val _testData3 = demoRepository.getData3AsFlow()

    override val mainList = combine(_testData1, _testData2, _testData3) { testData1, testData2, testData3 ->
        setListData(testData1, testData2, testData3)
    }.flowOn(Dispatchers.Default)
            .asLiveData()

    init {
        viewModelScope.launch(Dispatchers.IO) {
            demoService.getData()
        }
    }

    private suspend fun setListData(testData1: List<DemoData1>, testData2: List<DemoData2>, testData3: List<DemoData3>): List<CombinedData> {
        // package the three data elements up to one list of rows

        ...
    }

}

这是我的 Repository/DAO 层(对每种类型的数据重复)

@Query("SELECT * FROM demo_data_1_table")
abstract fun getData1AsFlow() : Flow<List<DemoData1>>

我可以通过删除 combine 函数中的 flowOn 来解决这个问题。删除那个电话后,我不再有问题了。

我仍然想 运行 默认调度程序上的 setListData 函数,所以我只是更改了 setListData 中的上下文。

class DemoViewModel @Inject constructor(
        demoService: DemoService,
        private val demoRepository: DemoRepository
) : ViewModel() {

    private val _testData1 = demoRepository.getData1AsFlow()
    private val _testData2 = demoRepository.getData2AsFlow()
    private val _testData3 = demoRepository.getData3AsFlow()

    override val mainList = combine(_testData1, _testData2, _testData3) { testData1, testData2, testData3 ->
        setListData(testData1, testData2, testData3)
    }.asLiveData()

    init {
        viewModelScope.launch(Dispatchers.IO) {
            demoService.getData()
        }
    }

    private suspend fun setListData(testData1: List<DemoData1>, testData2: List<DemoData2>, testData3: List<DemoData3>): List<CombinedData> = withContext(Dispatchers.Default) {
        // package the three data elements up to one list of rows

        ...
    }

}