Android使用 Combine 和 Stateflow同时调用多个API

Android使用 Combine 和 Stateflow同时调用多个API

API来了
在这里,我解释了如何将多个 API(或任何其他数据提供者)组合在一起以在 Android 应用程序中实现复杂的页面。

在当前的现代 Android 应用程序中,有时我们应该显示来自多个数据源的数据,所有数据的状态都很重要。

在本文中,我将 MVVM、Koin 和存储库模式与协程规则结合使用。

想象一下,我们想要设计一个页面来显示来自 API 1 和 API 2 的数据列表。它们应该组合起来显示数据,当每个数据都来自不同的存储库时,它会变得更加复杂。

或者即使每次数据发生变化,我们应该如何更新我们的页面?

联合收割机是viewModel,装卸车是Fragment
卡车是combine,小汽车是APIs
假设我们有 3 个名为exchangeOverviewrollingPricewatchList的 API 调用,但最后我们只需要一个数据,我们将其称为fullList

private val exchangeOverView = MutableStateFlow<Result<ExchangeOverview>>(Result.Loading)
private val rollingPrice =
    MutableStateFlow<Result<HashMap<String, RollingPrice>>?>(Result.Loading)
private val watchList = MutableStateFlow<Result<List<Coin>>?>(Result.Loading)

结果类如下所示

sealed class Result<out T : Any> {
    
    
    data class Success<out T : Any>(val data: T?) : Result<T>()
    data class Error(val exception: String, val errorCode: Int) : Result<Nothing>()
    object Loading : Result<Nothing>()
}

对于Stateflow的默认部分,我们使用Result.Loading,因为我们没有任何缓存(如果需要我们可以把它作为Stateflow的默认值)。

为什么不使用 Sharedflow

因为我们需要每个 API 的最后状态,并且我们想在多个新/旧页面中使用它,因此我们使用 Stateflow 而不是 Sharedflow

我们不知道所有 API 何时都成功,但我们知道希望所有 API 都准备就绪。
就是这样!这里我们的函数看起来像这样:

扫描二维码关注公众号,回复: 14696227 查看本文章
private suspend fun getExchangeOverview() {
    
    
    exchangeRepository.getExchangeOverview().collect {
    
     result ->
        when (result) {
    
    
            is Result.Loading -> {
    
    
                exchangeOverView.emit(Result.Loading)
            }

            is Result.Success -> {
    
    
                exchangeOverView.emit(Result.Success(result.data))
            }
            is Result.Error -> {
    
    
                exchangeOverView.emit(Result.Error(result.exception, result.errorCode))
            }
        }
    }
}

对于所有其他 API,我们使用的功能相同。

为了组合它们,我们使用下面的函数,当所有 API 都成功时我们只发出成功,并且 fof 失败和加载我们有自定义功能。

private fun combineData(): StateFlow<Result<List<SymbolsItem>>?>? =
    combine(
        exchangeOverView,
        rollingPrice,
        watchList
    ) {
    
     exchangeOverView, rollingPrice, wattchList ->
        if (exchangeOverView is Result.Success && rollingPrice is Result.Success && wattchList is Result.Success && currentUserState.value) {
    
    
val data = ourFunctionForUseAllDataToghether()
            Result.Success(data)
        } else if (exchangeOverView is Result.Error) {
    
    
            Result.Error(exchangeOverView.exception, exchangeOverView.errorCode)
        } else if (rollingPrice is Result.Error) {
    
    
            Result.Error(rollingPrice.exception, rollingPrice.errorCode)
        } else {
    
    
            Result.Loading
        }
    }.stateIn(viewModelScope, SharingStarted.Eagerly, null)
_fullDataStateFlow = combineData()

好的,我们的数据可以使用了。

在 Fragment/Activity 中我们调用了:

lifecycleScope.launchWhenResumed {
    
    
    viewModel.fullListData.collectLatest {
    
     result ->
        when (result) {
    
    
            is Result.Loading -> {
    
    
                shwoLoading()          
            }
            is Result.Success -> {
    
    
                showData()
            }
            is Result.Error -> {
    
    
                showError()
            }
        }
    }
}

API success

参考

https://medium.com/@keyvan.nrz/call-multile-api-calls-with-combine-and-stateflow-1cf4ea4ac322

猜你喜欢

转载自blog.csdn.net/u011897062/article/details/129924863