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

Android技术疑问:在Repository层轮询API是否合理?

Repository定时轮询数据实现的问题与优化方案

你当前在Repository的初始化块中,通过GlobalScope.launch启动了一个无限协程,每隔5秒调用getData()接口获取数据,成功时更新本地data字段,并且会将这个Repository注入到所有需要的ViewModel中。对应的初始化代码如下:

init {
    GlobalScope.launch {
        while(true) {
            when (val response = getData()) {
                is ApiResponse.Success -> {
                    response.data?.let {
                        data = it
                    }
                }
                else -> {}
            }
            delay(5000)
        }
    }
}

现有实现存在的问题

  • GlobalScope的风险:GlobalScope属于全局协程作用域,它的生命周期不受Repository或ViewModel的约束。即便相关组件已经被销毁,这个轮询协程仍会持续运行,不仅会造成内存泄漏,还会在后台无谓消耗系统资源。
  • 错误处理缺失:代码仅处理了接口返回成功的情况,对请求失败、抛出异常等分支完全没有处理,既不利于排查问题,也无法给上层业务提供错误反馈。
  • 数据更新无通知:如果data是普通变量,ViewModel无法感知到它的变化,UI层也无法自动响应数据更新,达不到数据驱动UI的效果。

优化建议

  1. 替换全局协程作用域
    为Repository创建专属的CoroutineScope,让协程生命周期与Repository绑定。在Repository被销毁时,调用scope.cancel()终止所有协程。示例:

    class YourRepository(private val externalScope: CoroutineScope) {
        private val scope = externalScope + CoroutineName("RepositoryPolling")
        
        // ... 其他代码
        
        fun cleanUp() {
            scope.cancel()
        }
    }
    
  2. 完善错误处理逻辑
    在分支中添加日志记录或异常处理,方便问题排查:

    when (val response = getData()) {
        is ApiResponse.Success -> {
            response.data?.let {
                _data.value = it
            }
        }
        is ApiResponse.Error -> {
            Log.e("YourRepository", "数据请求失败: ${response.errorMessage}")
        }
        is ApiResponse.Exception -> {
            Log.e("YourRepository", "数据请求抛出异常", response.exception)
        }
    }
    
  3. 使用可观察数据容器
    将data替换为MutableStateFlow(或LiveData),让ViewModel可以监听数据变化:

    private val _data = MutableStateFlow<YourDataType?>(null)
    val data: StateFlow<YourDataType?> = _data // 对外暴露只读流
    
    init {
        scope.launch {
            while(isActive) { // 用isActive判断协程是否存活,避免不必要的循环
                val response = getData()
                when (response) {
                    is ApiResponse.Success -> response.data?.let { _data.value = it }
                    is ApiResponse.Error -> Log.e("YourRepository", "请求失败: ${response.errorMessage}")
                    is ApiResponse.Exception -> Log.e("YourRepository", "请求异常", response.exception)
                }
                delay(5000)
            }
        }
    }
    
  4. 添加协程存活判断
    在循环中通过isActive判断协程是否还处于活跃状态,避免协程被取消后仍执行无效逻辑。

内容的提问来源于stack exchange,提问作者Hasan Syed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:10:30