You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Retrofit2+Jetpack Compose添加数据后,如何最优刷新服务器数据?

Jetpack Compose + Retrofit2 数据添加后列表刷新最优方案

在Jetpack Compose场景下使用Retrofit2实现数据增查操作时,添加新数据返回列表页后,新数据无法实时显示——原因是页面初始化时API请求已完成,仅重启应用才能读取到新数据。以下是几种最优刷新方案:

一、直接触发刷新(最易实现)

在数据添加操作成功后,主动调用列表数据的API请求方法,强制拉取最新数据。

代码修改示例

ViewModel中添加数据的方法内,成功回调后调用刷新:

// 假设添加数据的UseCase调用逻辑
fun addCampaign(campaign: Campaign) {
    addCampaignUseCase(campaign).onEach { response ->
        when (response) {
            is Resource.Success -> {
                // 添加成功后立即刷新列表数据
                getCampaigns()
            }
            is Resource.Loading -> { /* 加载状态处理 */ }
            is Resource.Error -> { /* 错误状态处理 */ }
        }
    }.launchIn(viewModelScope)
}

Composable中通过收集ViewModel的StateFlow自动更新UI:

@Composable
fun CampaignListScreen(viewModel: CampaignViewModel = hiltViewModel()) {
    val currentCampaigns by viewModel.campaignListCurrent.collectAsState()
    val completedCampaigns by viewModel.campaignListCompleted.collectAsState()
    val isLoading by viewModel.isLoadingProgressBar.collectAsState()

    // 列表UI渲染逻辑...
}

二、用SharedFlow实现刷新触发器

通过SharedFlow作为刷新事件的触发器,避免在每个数据修改操作后重复调用刷新方法,实现解耦。

代码修改示例

ViewModel中定义触发器并监听:

private val refreshTrigger = MutableSharedFlow<Unit>(replay = 0)
val campaignListCurrent = MutableStateFlow<List<Campaign>>(emptyList())
val campaignListCompleted = MutableStateFlow<List<Campaign>>(emptyList())
val isLoadingProgressBar = MutableStateFlow(false)

init {
    viewModelScope.launch {
        // 监听刷新事件,触发时重新拉取数据
        refreshTrigger.collect {
            getCampaigns()
        }
    }
}

// 对外暴露的刷新触发方法
fun triggerRefresh() {
    viewModelScope.launch {
        refreshTrigger.emit(Unit)
    }
}

// 添加数据成功后触发刷新
fun addCampaign(campaign: Campaign) {
    addCampaignUseCase(campaign).onEach { response ->
        if (response is Resource.Success) triggerRefresh()
    }.launchIn(viewModelScope)
}

三、服务器推送实现实时同步(类似Firebase)

如果需要类似Firebase实时数据库的自动同步效果,需要后端支持WebSocket或Server-Sent Events(SSE),服务器数据变更时主动推送给客户端,无需客户端主动轮询。

SSE实现示例

  1. 添加依赖:
implementation "com.squareup.retrofit2:adapter-rxjava3:2.9.0"
implementation "io.reactivex.rxjava3:rxjava:3.1.5"
  1. 定义SSE接口:
interface ApiServices {
    @GET("campaigns/sse")
    fun getCampaignsSse(): Observable<CampaignUpdate>
}
  1. ViewModel中监听推送更新:
fun observeRealTimeUpdates() {
    apiServices.getCampaignsSse()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe({ update ->
            // 根据服务器推送的更新类型修改本地列表
            when (update.type) {
                UpdateType.ADD -> {
                    val updatedList = campaignListCurrent.value.toMutableList()
                    updatedList.add(update.campaign)
                    campaignListCurrent.value = updatedList
                }
                UpdateType.DELETE -> {
                    val updatedList = campaignListCurrent.value.filter { it.id != update.campaign.id }
                    campaignListCurrent.value = updatedList
                }
            }
        }, { error ->
            // 处理连接错误,比如尝试重连
        })
}

四、优化本地数据维护:用StateFlow持有完整列表

避免手动维护MutableList导致的数据不同步,直接用StateFlow持有完整的列表数据,每次刷新直接替换列表,Composable通过收集StateFlow自动更新UI。

代码修改示例

ViewModel的getCampaigns()方法优化:

private fun getCampaigns() {
    getCampaignsUseCase().onEach { response ->
        when (response) {
            is Resource.Loading -> {
                isLoadingProgressBar.value = true
            }
            is Resource.Success -> {
                isLoadingProgressBar.value = false
                // 直接替换列表数据,避免手动增删
                val currentData = response.data?.data?.current?.items?.data.orEmpty().drop(1)
                val completedData = response.data?.data?.completed?.items?.data.orEmpty().drop(1)
                campaignListCurrent.value = currentData
                campaignListCompleted.value = completedData
            }
            is Resource.Error -> {
                isLoadingProgressBar.value = false
                // 错误日志处理...
            }
        }
    }.launchIn(viewModelScope)
}

内容的提问来源于stack exchange,提问作者Ahmed Rabee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 05:25:38