Android 网络层最佳实践:Retrofit + OkHttp 封装与实战

📖 目录

  1. 前言

  2. [为什么要封装 Retrofit + OkHttp](#为什么要封装 Retrofit + OkHttp)

  3. 基础封装思路

  4. [支持多 BaseUrl 的设计](#支持多 BaseUrl 的设计)

  5. 统一响应模型与错误处理

  6. [Token 自动刷新机制](#Token 自动刷新机制)

  7. 完整网络层结构

  8. 性能优化与调试建议

  9. 结语


💬 前言

在 Android 项目开发中,网络请求几乎是所有业务模块的基础。而在众多方案中,Retrofit + OkHttp 无疑是最稳定、最高效的组合。

它不仅支持注解式接口定义、自动序列化,还能与协程完美结合,轻松实现异步网络通信。

本文将从基础到进阶,带你实现一套「企业级」网络层封装,让你的代码更优雅、更安全、更可维护。


⚙️ 为什么要封装 Retrofit + OkHttp

在小型项目中,直接使用 Retrofit 足够简单;

但随着业务扩展,你可能会遇到以下痛点:

  • 不同模块需要使用 不同的 BaseUrl

  • 接口响应结构不一致,需要统一解析;

  • Token 失效需要自动刷新;

  • 需要统一的异常处理机制;

  • 想让 ViewModel 调用更简洁。

这些问题如果不统一封装,会导致项目结构混乱、维护困难。

因此,我们需要构建一个「高内聚、低耦合」的网络请求框架。


🧱 基础封装思路

Retrofit 是一个「上层封装」,核心依赖 OkHttp:

层级 功能 说明
OkHttp 网络层 负责请求发送、拦截、缓存、超时
Retrofit 封装层 负责接口注解解析、数据转换
协程 + Result 安全层 负责异常捕获与结果返回

我们将从 OkHttp 开始封装,逐步构建整个网络体系。


🌐 支持多 BaseUrl 的设计

1. 使用场景

在多模块项目中,不同业务接口往往属于不同域名:

模块 BaseUrl
用户中心 https://user.api.example.com/
支付模块 https://pay.api.example.com/
上传模块 https://upload.api.example.com/

Retrofit 默认只能设置一个 baseUrl

因此我们需要通过 拦截器 + Header 标识 来动态替换。


2. BaseUrlInterceptor.kt

Kotlin 复制代码
class BaseUrlInterceptor : Interceptor {

    companion object {
        const val HEADER_BASE_URL = "Base-Url" // 自定义 Header 名
    }

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val baseUrlHeader = request.header(HEADER_BASE_URL)

        // 如果请求头中包含自定义 BaseUrl
        if (!baseUrlHeader.isNullOrEmpty()) {
            val newUrl = request.url.newBuilder()
                .scheme("https")
                .host(baseUrlHeader)
                .build()

            val newRequest = request.newBuilder()
                .url(newUrl)
                .removeHeader(HEADER_BASE_URL) // 使用完后移除
                .build()

            return chain.proceed(newRequest)
        }

        // 默认请求
        return chain.proceed(request)
    }
}

3. RetrofitManager.kt

Kotlin 复制代码
object RetrofitManager {

    private const val DEFAULT_BASE_URL = "https://user.api.example.com/"

    private val okHttpClient by lazy {
        OkHttpClient.Builder()
            .addInterceptor(BaseUrlInterceptor())
            .addInterceptor(TokenInterceptor())
            .addInterceptor(HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY
            })
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(15, TimeUnit.SECONDS)
            .build()
    }

    fun getService(baseUrl: String = DEFAULT_BASE_URL): Retrofit {
        return Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
}

使用示例:

Kotlin 复制代码
val userApi = RetrofitManager.getService().create(UserApi::class.java)
val payApi = RetrofitManager.getService("https://pay.api.example.com/").create(PayApi::class.java)

🧩 统一响应模型与错误处理

1. 定义统一返回结构

Kotlin 复制代码
data class BaseResponse<T>(
    val code: Int,
    val msg: String?,
    val data: T?
) {
    fun isSuccess() = code == 200
}

2. 安全请求封装(协程版)

Kotlin 复制代码
suspend fun <T> safeApiCall(apiCall: suspend () -> BaseResponse<T>): Result<T> {
    return try {
        val response = apiCall()
        if (response.isSuccess()) {
            Result.success(response.data!!)
        } else {
            Result.failure(Exception(response.msg ?: "未知错误"))
        }
    } catch (e: IOException) {
        Result.failure(Exception("网络连接失败"))
    } catch (e: HttpException) {
        Result.failure(Exception("网络错误: ${e.code()}"))
    } catch (e: Exception) {
        Result.failure(e)
    }
}

3. ViewModel 调用示例

Kotlin 复制代码
class LoginViewModel : ViewModel() {

    private val _loginState = MutableLiveData<Result<LoginResponse>>()
    val loginState: LiveData<Result<LoginResponse>> = _loginState

    fun login(username: String, password: String) {
        viewModelScope.launch {
            val result = safeApiCall {
                RetrofitManager.getService().create(UserApi::class.java)
                    .login(username, password)
            }
            _loginState.value = result
        }
    }
}

🔑 Token 自动刷新机制

Kotlin 复制代码
class TokenInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request().newBuilder()
            .addHeader("Authorization", "Bearer ${TokenManager.token}")
            .build()

        val response = chain.proceed(request)

        // Token 过期处理
        if (response.code == 401) {
            synchronized(this) {
                val newToken = TokenManager.refreshToken()
                if (newToken != null) {
                    val newRequest = request.newBuilder()
                        .removeHeader("Authorization")
                        .addHeader("Authorization", "Bearer $newToken")
                        .build()
                    return chain.proceed(newRequest)
                }
            }
        }
        return response
    }
}

📦 网络层完整结构

复制代码
network/
├── ApiService.kt          # 接口定义
├── RetrofitManager.kt     # Retrofit 实例
├── BaseUrlInterceptor.kt  # 多域名支持
├── TokenInterceptor.kt    # Token 刷新
├── NetworkHelper.kt       # 安全请求封装
└── model/
    └── BaseResponse.kt    # 统一响应模型

⚡ 性能优化与调试建议

优化项 建议
⏱️ 超时设置 连接 10s,读取 15s,写入 15s
🧠 缓存策略 静态接口可添加本地缓存
🔍 日志管理 Debug 模式启用 BODY,Release 模式关闭
♻️ 连接池复用 默认 Keep-Alive,可减少握手时间
🧩 异常监控 在 Result.failure 中上报错误信息

🏁 结语

通过这套封装,我们构建了一个高扩展性、高可维护性的网络层:

层级 功能 示例
通信层 OkHttp 超时、缓存、拦截器
封装层 Retrofit 动态接口映射
逻辑层 协程 + Result 异常捕获、安全返回
扩展层 Token、多 BaseUrl 统一管理

🔧 这是一套可以直接落地于实际项目的通用网络架构,既简洁又灵活,适用于 MVVM、MVI 等主流架构。

相关推荐
信田君95274 小时前
瑞莎星瑞(Radxa Orion O6) 基于 Android OS 使用 NPU的图片模糊查找APP 开发
android·人工智能·深度学习·神经网络
tangweiguo030519875 小时前
Kotlin 实现 Android 网络状态检测工具类
android·网络·kotlin
nvvas6 小时前
Android Studio JAVA开发按钮跳转功能
android·java·android studio
怪兽20146 小时前
Android多进程通信机制
android·面试
叶羽西7 小时前
Android CarService调试操作
android
千里马-horse7 小时前
在android中 spdlog库的log如何在控制台上输出
android·c++·spdlog
Zender Han7 小时前
《从零搭建现代 Android 模块化架构项目(2025 最新实践)》
android·架构
Digitally8 小时前
如何从电脑上卸载安卓应用程序
android·电脑
Mr YiRan8 小时前
多线程性能优化基础
android·java·开发语言·性能优化