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のドキュメントから:
強い平等に基づく対立
状態フローの値は、distinctUntilChanged演算子と同様の方法で、Any.equals比較を使用して統合されます。これは、受信した更新をMutableStateFlowの値に統合し、新しい値が以前に発行された値と等しい場合にコレクターへの値の発行を抑制するために使用されます。Any.equalsのコントラクトに違反するクラスでの状態フローの動作は指定されていません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加