java - Kotlin - MutableStateFlow Emision 从未收到
问题描述
当我在不同的片段中更改 GameData 的 isInFavorites 属性时,我可以看到在我的存储库的侦听器中收到了更改,但是当我导航回片段时,当我使用 MutableStateFlow 时,我的视图模型永远不会收到更新的值。
奇怪的是,当我将流程更改为 MutableSharedFlow 时,突然之间,视图模型也开始获取更新的值。有谁知道为什么会发生这种情况?我需要在这里使用 MutableStateFlow 并且它不起作用。
存储库:
private val gameDataListResultMutableFlow: MutableStateFlow<Result<List<GameData>>> = MutableStateFlow(Result.Loading)
override suspend fun observeGameDataList(): Flow<Result<List<GameData>>>
{
CoroutineScope(Dispatchers.IO + coroutineContext).launch {
localGameDataSource.observeGameDataList().collectLatest{
if(it is Result.Success)
{
Timber.d("local data change favorite value of item 0: ${it.data[0].isInFavorites}")
}
gameDataListResultMutableFlow.emit(it)
}
}
}
视图模型:
private suspend fun observeGameListResult()
{
gameRepository.observeGameDataList().collect{
if(it is Result.Success)
Timber.d("data change received in viewmodel value of item 0: ${it.data[0].isInFavorites}")
gameListResultMutableLiveData.postValue(it)
}
}
fun getGameListResultLiveData(): LiveData<Result<List<GameData>>>
{
launch(coroutineContext) {
observeGameListResult()
}
return gameListResultMutableLiveData
}
使用 StateFlow 时的日志
LOADING THE INITIAL STATE, ISFAVORITE VALUE IS TRUE
D/DefaultGameRepository: local data change favorite value of item 0: true
D/GameListViewModel: data change received in viewmodel value of item 0: true
SWITCHING TO ANOTHER FRAGMENT TO CHANGE THE ISFAVORITE'S VALUE TO FALSE, WHICH IS RECEIVED ONLY BY
THE LOCAL SOURCE LISTENER
D/DefaultGameRepository: local data change the favorite value of item 0: false
SWITCHING BACK TO THE INITIAL FRAGMENT AND THE UPDATED VALUE OF THE ISFAVORITE REFLECTED ON THE LOCAL SOURCE LISTENER BUT NOT ON THE VIEWMODEL LISTENER---
D/GameListViewModel: data change received in viewmodel value of item 0: true
D/DefaultGameRepository: local data change the favorite value of item 0: false
使用 SharedFlow 时的日志:
LOADING THE INITIAL STATE, ISFAVORITE VALUE IS TRUE
D/DefaultGameRepository: local data change the favorite value of item 0: true
D/GameListViewModel: data change received in viewmodel value of item 0: true
SWITCHING TO ANOTHER FRAGMENT TO CHANGE THE ISFAVORITE'S VALUE TO FALSE, WHICH IS RECEIVED BY LOCAL
SOURCE AND THE VIEWMODEL LISTENER
D/DefaultGameRepository: local data change the favorite value of item 0: false
D/GameListViewModel: data change received in viewmodel value of item 0: false
SWITCHING BACK TO THE INITIAL FRAGMENT AND THE UPDATED VALUE OF THE ISFAVORITE REFLECTED ON THE
VIEWMODEL
D/DefaultGameRepository: local data change the favorite value of item 0: false
D/GameListViewModel: data change received in viewmodel value of item 0: false
D/GameListViewModel: data change received in viewmodel value of item 0: false
解决方案
是的,所以可能主要原因是 MutableStateFlow 不会发出,除非提议的要发出的对象不等于旧值。然而,MutableSharedFlow 将始终发出,因为它的发出逻辑没有distinctUntilChanged()
等于逻辑。
从 SharedFlow 文档:
强基于平等的合并
状态流中的值使用 Any.equals 比较以类似于 distinctUntilChanged 运算符的方式进行合并。它用于将传入的更新与 MutableStateFlow 中的值合并,并在新值等于先前发出的值时抑制向收集器发出值。未指定违反 Any.equals 合同的类的状态流行为。
推荐阅读
- javascript - Angular - 在路由中传递数据
- android - 在检查文件夹是否存在或列出其子文件夹之前,我是否必须检查 READ_EXTERNAL_STORAGE
- typescript - 带有 Typeorm 事务的 Nestjs 存储库模式
- python - 将 Python 3.7 添加到 Anaconda
- php - 如何在包含之前定义路径处理程序?
- r - 如何在 Shiny App 中使用多个数据集?
- azure-ad-b2c - 为什么我在尝试上传 B2C 索赔文件时收到验证错误。策略 xml 'yourtenant.onmicrosoft.com' 在哪里
- yocto - 如何在 Yocto bitbake 编译步骤中剥离和 objcopy 构建的 .so 文件?
- excel - 使用 VBA 将所选国家(行)和两个定义日期(列)之间的数据复制到工作表?
- java - Java:排序的多图,它是列表的映射而不是集合的映射