Android Room @Transaction未按预期工作:Flow在事务中间触发
Room事务中Flow提前触发数据发射的问题
我在Room DAO中定义了带@Transaction注解的refreshInboxMessages方法,逻辑是先执行deleteAll再执行insertAll,但发现getAllFlow会在deleteAll完成、insertAll执行前发射空列表,而非等整个事务完成后再发射数据。我尝试过用@Transaction注解,也试过runInTransaction{},都没能解决这个问题。
我的DAO代码如下:
private const val RECENT_UPDATE_THRESHOLD_MS = 60_000L @Dao interface InboxMessageDao { @Query( "SELECT * FROM inbox_message " + "WHERE toEmail == (SELECT email FROM email_address WHERE isCurrent = 1) " + "AND (strftime('%s', 'now') * 1000 - cacheLastUpdate) < $RECENT_UPDATE_THRESHOLD_MS" ) fun getAllFlow(): Flow<List<InboxMessageEntity>> @Insert suspend fun insertAll(messages: List<InboxMessageEntity>) @Query("DELETE FROM inbox_message") suspend fun deleteAll() @Query("SELECT cacheLastUpdate FROM inbox_message WHERE toEmail == :toEmail LIMIT 1") suspend fun getCacheLastUpdate(toEmail: String): Long? @Transaction // TODO: This fails tests sometimes, why? suspend fun refreshInboxMessages(newMessages: List<InboxMessageEntity>) { deleteAll() // Flow seems to be propagated here giving me sometimes empty list in androidTests insertAll(newMessages) } }
我期望Flow能在整个事务执行完成后再发射数据。
附上我的Android测试用例:
@Test fun shouldPropagateOneMessage() = runTest { // given coEvery { repository.getInboxMessagesFromApi() } returns listOf(inboxMessage) val viewModel = InboxMessageViewModel(StandardTestDispatcher(testScheduler)) advanceUntilIdle() // expect val result = viewModel.uiState.first() advanceUntilIdle() assertThat(result).isEqualTo(ViewModelState.Success(listOf(inboxMessage))) }
测试偶尔会失败,原因是Flow发射了空列表,导致ViewModel触发了ViewModelState.Empty状态。
内容的提问来源于stack exchange,提问作者tomapplause
相关产品推荐
相关产品推荐

