【问题标题】:Kotlin Flow in ViewModel doesn't emit data from Room table sometimesViewModel 中的 Kotlin Flow 有时不会从 Room 表中发出数据
【发布时间】:2020-11-16 19:40:05
【问题描述】:

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

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

我正在使用的版本:

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

这是我的视图模型

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

        ...
    }

}

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

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

【问题讨论】:

    标签: android kotlin android-room viewmodel kotlin-coroutines


    【解决方案1】:

    我可以通过在 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
    
            ...
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-30
      • 1970-01-01
      • 2018-06-07
      • 2021-11-18
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多