Room返回的Flow使用stateIn无效,改用shareIn却正常工作
相关代码
DAO代码
@Query("SELECT * FROM reminders") fun getAll(): Flow<List<ReminderEntity>>
Repository代码
override fun getAllRemindersAsFlow(): Flow<List<Reminder>> { return mRemindersDao.getAll().map { Log.e("TAG", "room emitting") it.map(ReminderEntity::toDomain) } }
ViewModel代码(无法正常工作的两种写法)
第一种写法:
val reminders = mRemindersRepository.getAllRemindersAsFlow().stateIn( scope = viewModelScope, started = SharingStarted.Eagerly, initialValue = emptyList() )
第二种写法(添加distinctUntilChanged后依然无效):
val reminders = mRemindersRepository.getAllRemindersAsFlow().distinctUntilChanged { old, new -> // old和new相等时返回true old == new }.stateIn( scope = viewModelScope, started = SharingStarted.Eagerly, initialValue = emptyList() )
Fragment的onViewCreated方法代码
lifecycleScope.launch { mViewModel.reminders.collectLatest { reminders -> Log.e("TAG", "onViewCreated: Updated") when (mBinding.remindersBottomNavigationView.selectedItemId) { R.id.upcoming_reminders -> if (reminders.isEmpty()) { mBinding.reminderHelpLabel.setText(R.string.no_upcoming_reminder) } else mRemindersRecyclerViewAdapter.setReminders(reminders.filter(Reminder::isUpcoming)) R.id.all_reminders -> if (reminders.isEmpty()) { mBinding.reminderHelpLabel.setText(R.string.click_to_create_a_reminder) } else mRemindersRecyclerViewAdapter.setReminders(reminders) } } }
问题现象
更新提醒时,日志中能看到Room emitting,但onViewCreated: Updated无输出,UI也未更新。
通过日志确认列表确实发生了变化:
- 更新前Room输出:
room emitting: ReminderEntity(id=8, title=Test, time=[1035, 1165], days=[Tue], enabled=false) room emitting: ReminderEntity(id=9, title=Test, time=[1040, 1115, 1110], days=[Sun, Mon, Tue, Wed, Thu, Fri, Sat], enabled=true) room emitting: ReminderEntity(id=17, title=yui, time=[1415], days=[Sun, Mon, Tue, Wed, Thu, Fri, Sat], enabled=true)
- 禁用一个提醒后Room输出:
room emitting: ReminderEntity(id=8, title=Test, time=[1035, 1165], days=[Tue], enabled=false) room emitting: ReminderEntity(id=9, title=Test, time=[1040, 1115, 1110], days=[Sun, Mon, Tue, Wed, Thu, Fri, Sat], enabled=true) room emitting: ReminderEntity(id=17, title=yui, time=[1415], days=[Sun, Mon, Tue, Wed, Thu, Fri, Sat], enabled=false)
可见最后一条提醒的enabled状态已修改,列表内容确实更新。
但将ViewModel代码改为以下形式后,UI能正常响应更新:
val reminders = mRemindersRepository.getAllRemindersAsFlow().shareIn( scope = viewModelScope, started = SharingStarted.Eagerly, replay = 1 )
内容的提问来源于stack exchange,提问作者OhhhThatVarun
相关产品推荐
相关产品推荐

