当我在另一个 fragment 中更改 GameData 的 isInFavorites 属性时,我可以看到我的存储库的监听器中收到了更改,但是当我导航回该 fragment 时,我的 View 模型在我使用 MutableStateFlow 时从未收到更新的值。
奇怪的是,当我将流程更改为 MutableSharedFlow 时,突然间 viewmodel 也开始获取更新的值。有谁知道为什么会这样? 我需要在这里使用 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)
}
}
}
View 模型:
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 文档:
Strong equality-based conflation
Values in state flow are conflated using Any.equals comparison in a similar way to distinctUntilChanged operator. It is used to conflate incoming updates to value in MutableStateFlow and to suppress emission of the values to collectors when new value is equal to the previously emitted one. State flow behavior with classes that violate the contract for Any.equals is unspecified.
关于java - Kotlin - MutableStateFlow Emmision 从未收到,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65703272/