为何该函数返回空列表?已设置初始值却未生效
问题原因与解决方法
你设置的initialValue只会在订阅者刚订阅、上游Flow还没发出任何数据的时候生效。但Room数据库的查询Flow有个特性:一旦订阅,它会立即执行查询并发出结果——哪怕没有匹配的数据,也会发出一个空列表。所以你的初始值会被这个空列表立刻覆盖,最终看到的就是空列表。
解决办法
如果你希望数据库无匹配数据时始终返回包含默认Flashcard的列表,需要在上游Flow中处理空结果,而不是只依赖stateIn的初始值:
修改Repository层的Flow(推荐)
在flashcardsRepository.getFlaggedFlashcardsStreamFilteredByTopic返回的Flow上添加map操作,把空列表替换成你想要的默认值:
// 在Repository的实现中修改 fun getFlaggedFlashcardsStreamFilteredByTopic(topic: String): Flow<List<Flashcard>> { return dao.getFlaggedFlashcardsFilteredByTopic(topic) .map { flashcards -> // 如果查询结果为空,返回包含默认Flashcard的列表 if (flashcards.isEmpty()) listOf(Flashcard()) else flashcards } }
或者在ViewModel层处理
如果不想改动Repository,也可以在ViewModel的函数中对上游Flow做同样的处理:
fun getFlaggedFlashcardsFilteredByTopic(topic: String): StateFlow<List<Flashcard>> { return flashcardsRepository.getFlaggedFlashcardsStreamFilteredByTopic(topic = topic) .map { flashcards -> if (flashcards.isEmpty()) listOf(Flashcard()) else flashcards } .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(timeoutMillis), initialValue = listOf(Flashcard()) // 现在这个初始值会在数据库查询完成前临时生效 ) }
这样不管数据库返回空还是有数据,最终的StateFlow都会符合你的预期:空结果时返回带默认抽认卡的列表,有数据时返回实际查询结果。
内容的提问来源于stack exchange,提问作者Allen J Mathew
相关产品推荐
相关产品推荐

