Datastore - flow no 在更改后发出新值

问题描述 投票:0回答:1

我无法接收数据存储中的更改。在主屏幕的设置中更改数据库模式后,应用程序应该观察另一个数据源。

@Singleton
class SettingsRepositoryImpl @Inject constructor(
    @ApplicationContext private val context: Context
) : SettingsRepository {
    private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_prefs")

 override val databaseMode: Flow<String>
        get() =
            context.dataStore.data.map { preferences ->
                preferences[DATABASE_MODE_KEY] ?: DatabaseMode.LOCAL.name
            }.distinctUntilChanged()

/// Viewmodel ->
viewModelScope.launch(Dispatchers.Default) {
            observeDatabaseModeUseCase().collect { databaseMode ->
                observeAllProductsUseCase(databaseMode).map { products ->
                    getFilteredProductListUseCase(
                        products,
                        filterProductDataState.value.filterProduct
                    )
                }.collect {
                    _uiState.value = MyPantryProductsUiState.Loaded(
                        MyPantryModel(
                            groupsProduct = getGroupProductListUseCase(it),
                            loadingVisible = false
                        )
                    )
                }
            }
        }

我试过所有调度员。我不知道为什么之后它没有发出新的值

android kotlin coroutine datastore flow
1个回答
0
投票

您正在另一个流的收集块中收集无限流。因此,当外部流中的第一个项目被发射时,它会开始永远收集内部流,并且永远不会发射外部流的第二个项目。改用

flatMapLatest
。这将使它在第一个流发出新项目时中断二次流。

//In ViewModel init:
observeDatabaseModeUseCase()
    .flatMapLatest { databaseMode ->
        observeAllProductsUseCase(databaseMode)
    }.map { products ->
        getFilteredProductListUseCase(
            products,
            filterProductDataState.value.filterProduct
        )
    }.onEach {
        _uiState.value = MyPantryProductsUiState.Loaded(
            MyPantryModel(
                groupsProduct = getGroupProductListUseCase(it),
                loadingVisible = false
            )
        )
    }
    .flowOn(Dispatchers.Default) // probably unnecessary since you don't seem to be doing blocking work.
    .launchIn(viewModelScope)

您没有显示

_uiState
是什么,但您可以使用上面的
stateIn
使其成为 StateFlow 以简化您的代码。

© www.soinside.com 2019 - 2024. All rights reserved.