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

本文介绍了如何在Android应用中使用Combine和Stateflow来集成多个API调用,特别是在MVVM架构和Koin依赖注入下。通过使用Stateflow来跟踪每个API的状态,开发者可以在所有数据准备就绪时组合并更新页面。文章还讨论了错误处理和在页面之间共享数据的策略。
摘要由CSDN通过智能技术生成

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 都准备就绪。
就是这样!这里我们的函数看起来像这样:

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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Calvin880828

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值