首页 > 解决方案 > 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

标签: javaandroidkotlinkotlin-coroutineskotlin-flow

解决方案


是的,所以可能主要原因是 MutableStateFlow 不会发出,除非提议的要发出的对象不等于旧值。然而,MutableSharedFlow 将始终发出,因为它的发出逻辑没有distinctUntilChanged()等于逻辑。

从 SharedFlow 文档:

强基于平等的合并

状态流中的值使用 Any.equals 比较以类似于 distinctUntilChanged 运算符的方式进行合并。它用于将传入的更新与 MutableStateFlow 中的值合并,并在新值等于先前发出的值时抑制向收集器发出值。未指定违反 Any.equals 合同的类的状态流行为。

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-state-flow/index.html


推荐阅读