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

如何借助Room与Retrofit简化MVVM架构的Repository函数

Android MVVM中Repository协程代码简化方案

原代码问题分析

原代码逻辑可行,但存在协程层级冗余(手动嵌套CoroutineScope+suspendCoroutine)、Retrofit回调与协程混用的问题,导致代码可读性差,还存在手动创建CoroutineScope引发的生命周期泄漏风险。

优化后完整代码

1. 改造Retrofit接口(支持协程)

interface StateApi {
    // 将原Call<T>改为suspend函数,Retrofit自动处理协程调度
    @GET("states")
    suspend fun states(): List<State>
}

2. 简化后的ViewModel

class WeatherViewModel @Inject constructor(private val stateRepository: StateRepository) : ViewModel() {
    val ldStates = MutableLiveData<List<State>?>()
    val ldWeather = MutableLiveData<Weather>()

    fun reqStates() {
        viewModelScope.launch {
            // viewModelScope默认在Main线程,获取结果后直接更新LiveData
            val res = stateRepository.reqStates()
            ldStates.value = res
        }
    }
}

3. 简化后的Repository

open class StateRepository @Inject constructor(
    private val api: StateApi, 
    private val db: StateDatabase
) {
    private val stateDao = db.stateDao()

    suspend fun reqStates(): List<State>? {
        // 统一切换到IO线程执行数据库查询和网络请求
        return withContext(Dispatchers.IO) {
            // 先查询本地数据库
            val localStates = stateDao.getAll()
            if (!localStates.isNullOrEmpty()) {
                localStates
            } else {
                try {
                    // 发起网络请求获取数据
                    val remoteStates = api.states()
                    // 保存数据到本地数据库
                    saveStatesInDB(remoteStates)
                    remoteStates
                } catch (e: Exception) {
                    // 网络请求失败时返回null
                    null
                }
            }
        }
    }

    // 改为suspend函数,在IO线程执行数据库操作
    private suspend fun saveStatesInDB(states: List<State>) {
        // 建议使用批量插入优化性能,需对应修改Dao的insert方法
        stateDao.insertAll(states)
    }
}

核心优化点

  • Retrofit协程化:将接口从Call<List<State>>改为suspend fun,彻底消除回调嵌套,Retrofit自动处理网络请求的线程调度。
  • 移除冗余协程层级:删掉原代码中手动创建CoroutineScope+suspendCoroutine的嵌套结构,利用suspend函数特性,通过withContext(Dispatchers.IO)统一调度IO操作,代码结构更简洁。
  • 数据库操作规范化:将saveStatesInDB改为suspend函数,避免手动创建无生命周期绑定的CoroutineScope,消除泄漏风险。
  • ViewModel逻辑简化:viewModelScope.launch默认运行在Main线程,获取结果后直接用ldStates.value = res更新LiveData,无需额外切换线程。
  • 异常统一处理:给网络请求添加try-catch,统一捕获异常并返回null,避免意外崩溃。

内容的提问来源于stack exchange,提问作者Denis Jung

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:35:21