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

如何在Android中用Retrofit简化网络响应处理的重复代码?

优化重复响应处理逻辑的方案

你当前在多个ViewModel中重复编写类似的响应处理方法,产生了大量样板代码,可以通过以下几种方式实现代码复用,保持整洁:

1. 提取泛型工具类

将通用的响应处理逻辑封装到一个独立的工具类中,利用泛型支持不同类型的Response和Resource:

object ApiResponseHandler {
    // 全局复用Gson实例,避免重复创建带来的性能损耗
    private val gson = Gson()

    fun <T> handleResponse(response: Response<T>): Resource<T> {
        return if (response.isSuccessful) {
            // 处理成功响应
            response.body()?.let { Resource.Success(it) } 
                ?: Resource.Failure("Response body is null")
        } else {
            // 解析错误体
            val errorBody = response.errorBody()?.charStream()?.let {
                gson.fromJson(it, ErrorBodyResponse::class.java)
            }
            // 根据状态码匹配错误信息
            val errorTitle = when(response.code()) {
                400 -> Constants.error400
                401 -> Constants.error401
                403 -> Constants.error403
                408 -> Constants.error408
                413 -> Constants.error413
                511 -> Constants.error511
                else -> "Something went wrong"
            }
            Resource.Failure(errorTitle, errorBody?.message)
        }
    }
}

使用方式

在ViewModel中直接调用工具类的方法,无需重复编写处理逻辑:

private fun handleResponse(response: Response<OtpSentDataClass>): Resource<OtpSentDataClass> {
    return ApiResponseHandler.handleResponse(response)
}

private fun handleDeviceDetailResponse(response: Response<DeviceDetailResponse>): Resource<DeviceDetailResponse> {
    return ApiResponseHandler.handleResponse(response)
}

2. 给Response添加扩展函数

利用Kotlin的扩展函数特性,直接给Retrofit的Response<T>类添加转换为Resource<T>的方法,进一步简化调用:

// 全局复用Gson实例
private val gson = Gson()

fun <T> Response<T>.toResource(): Resource<T> {
    return if (this.isSuccessful) {
        this.body()?.let { Resource.Success(it) } 
            ?: Resource.Failure("Response body is null")
    } else {
        val errorBody = this.errorBody()?.charStream()?.let {
            gson.fromJson(it, ErrorBodyResponse::class.java)
        }
        val errorTitle = when(this.code()) {
            400 -> Constants.error400
            401 -> Constants.error401
            403 -> Constants.error403
            408 -> Constants.error408
            413 -> Constants.error413
            511 -> Constants.error511
            else -> "Something went wrong"
        }
        Resource.Failure(errorTitle, errorBody?.message)
    }
}

使用方式

在网络请求回调中直接调用扩展方法,无需额外编写handleXXX方法:

// 示例:网络请求回调
fun fetchOtp() {
    viewModelScope.launch {
        val response = apiService.sendOtp(...)
        val resource = response.toResource()
        // 后续处理resource(更新UI状态等)
    }
}

3. 基于基类ViewModel封装通用逻辑

如果所有需要处理响应的ViewModel都可以继承一个基类,可将通用逻辑放在基类中:

open class BaseViewModel : ViewModel() {
    private val gson = Gson()

    // 受保护方法,子类可直接调用
    protected fun <T> handleApiResponse(response: Response<T>): Resource<T> {
        return if (response.isSuccessful) {
            response.body()?.let { Resource.Success(it) } 
                ?: Resource.Failure("Response body is null")
        } else {
            val errorBody = response.errorBody()?.charStream()?.let {
                gson.fromJson(it, ErrorBodyResponse::class.java)
            }
            val errorTitle = when(response.code()) {
                400 -> Constants.error400
                401 -> Constants.error401
                403 -> Constants.error403
                408 -> Constants.error408
                413 -> Constants.error413
                511 -> Constants.error511
                else -> "Something went wrong"
            }
            Resource.Failure(errorTitle, errorBody?.message)
        }
    }
}

使用方式

让你的ViewModel继承BaseViewModel,直接调用基类的通用方法:

class AuthViewModel : BaseViewModel() {
    private fun handleOtpResponse(response: Response<OtpSentDataClass>): Resource<OtpSentDataClass> {
        return handleApiResponse(response)
    }
}

内容的提问来源于stack exchange,提问作者Ashish Gautam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 23:24:47