【问题标题】:Kotlin - MutableStateFlow Emmision is Never ReceivedKotlin - MutableStateFlow Emision 从未收到
【发布时间】:2021-04-18 13:04:55
【问题描述】:

当我在不同的片段中更改 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

【问题讨论】:

    标签: java android kotlin kotlin-coroutines kotlin-flow


    【解决方案1】:

    是的,所以可能主要原因是 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

    【讨论】:

    • 我完全忘记了它的行为方式,因为我在比较我的模型类时故意忽略了我的 isFavorite 属性。非常感谢
    猜你喜欢
    • 2021-11-21
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多