一、前言
在 Android 开发中,网络请求几乎是每个项目必不可少的功能模块。
而 Retrofit + OkHttp 作为目前最主流、最稳定、最易扩展的网络请求组合,被广泛应用于各类项目中。
本篇文章将带你从底层原理到实战封装,全面掌握 Retrofit 与 OkHttp 的使用与优化技巧。
二、基础概念与架构关系
1. Retrofit 是什么?
Retrofit 是由 Square 公司开发的 RESTful 网络请求框架 ,它基于 OkHttp 实现底层请求,核心功能是:
-
将 HTTP 接口转化为 Java/Kotlin 接口;
-
通过注解定义请求方式;
-
支持多种数据解析器(Gson、Moshi、FastJson等);
-
支持协程与 RxJava。
Retrofit 本身不负责网络请求,只负责「封装请求与解析结果」。
2. OkHttp 是什么?
OkHttp 同样是 Square 开发的网络框架,是 Android 默认的 HTTP 客户端库(Android 6.0 起内置)。
它负责:
-
建立网络连接;
-
管理请求与响应;
-
提供拦截器机制;
-
支持连接池与缓存。
Retrofit 是"上层封装",OkHttp 是"底层驱动"。
3. 二者关系图
Retrofit │ ├── 注解解析(@GET、@POST 等) ├── 参数拼装(Request) ├── 结果解析(Converter) ▼ OkHttp ├── 建立连接 ├── 执行请求 ├── 返回 Response ▼ Retrofit 将 Response 转换成 Java 对象
三、基础使用示例
1. 添加依赖
Kotlin
dependencies {
// Retrofit 核心库
implementation 'com.squareup.retrofit2:retrofit:2.11.0'
// Gson 转换器
implementation 'com.squareup.retrofit2:converter-gson:2.11.0'
// OkHttp 核心库
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
// OkHttp 日志拦截器
implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0'
}
2. 定义 API 接口
Kotlin
interface ApiService {
// 示例:GET 请求
@GET("users/{id}")
suspend fun getUser(@Path("id") id: String): UserResponse
// 示例:POST 请求(表单)
@FormUrlEncoded
@POST("user/login")
suspend fun login(
@Field("username") username: String,
@Field("password") password: String
): LoginResponse
}
3. 构建 Retrofit 实例
Kotlin
object RetrofitClient {
private const val BASE_URL = "https://api.example.com/"
// OkHttpClient 构建
private val okHttpClient: OkHttpClient by lazy {
OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS) // 连接超时
.readTimeout(15, TimeUnit.SECONDS) // 读取超时
.writeTimeout(15, TimeUnit.SECONDS) // 写入超时
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY // 打印请求日志
})
.build()
}
// Retrofit 实例
val instance: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create()) // 使用 Gson 解析
.build()
}
// 获取 API Service
val api: ApiService by lazy { instance.create(ApiService::class.java) }
}
4. ViewModel 中使用(结合协程)
Kotlin
class UserViewModel : ViewModel() {
private val _user = MutableLiveData<UserResponse>()
val user: LiveData<UserResponse> = _user
fun fetchUser(id: String) {
viewModelScope.launch {
try {
val result = RetrofitClient.api.getUser(id)
_user.value = result
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
四、OkHttp 拦截器机制(核心)
拦截器是 OkHttp 最强大的功能之一,可以对请求和响应进行统一处理。
1. 日志拦截器
Kotlin
val logging = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
2. Token 拦截器(统一加 Header)
Kotlin
class TokenInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val newRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer ${TokenManager.token}")
.build()
return chain.proceed(newRequest)
}
}
3. 缓存拦截器
Kotlin
class CacheInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val response = chain.proceed(request)
return response.newBuilder()
.header("Cache-Control", "max-age=3600") // 缓存 1 小时
.build()
}
}
五、封装建议(可直接复用)
如果项目较大,可以创建一个统一的网络请求封装类:
Kotlin
object NetworkHelper {
suspend fun <T> safeApiCall(call: suspend () -> T): Result<T> {
return try {
Result.success(call())
} catch (e: HttpException) {
Result.failure(Exception("网络错误: ${e.code()}"))
} catch (e: IOException) {
Result.failure(Exception("连接失败,请检查网络"))
} catch (e: Exception) {
Result.failure(e)
}
}
}
使用示例:
Kotlin
viewModelScope.launch {
val result = NetworkHelper.safeApiCall {
RetrofitClient.api.getUser("123")
}
result.onSuccess {
// 成功
}.onFailure {
// 失败
}
}
六、性能优化建议
优化点 | 说明 |
---|---|
✅ 复用 OkHttpClient | 不要每次都 new 一个客户端,建议单例复用 |
✅ 启用连接池 | OkHttp 默认支持 Keep-Alive,减少 TCP 连接开销 |
✅ 开启缓存机制 | 为静态资源、图片、配置文件设置合理缓存 |
✅ 使用协程替代 Callback | 减少回调嵌套,提高可读性 |
✅ 拦截器链路分析 | 可调试日志拦截器,分析慢请求或 Header 问题 |
七、总结
模块 | 作用 | 关键特性 |
---|---|---|
Retrofit | 封装网络接口 | 注解式定义、数据解析、协程支持 |
OkHttp | 执行网络请求 | 连接池、缓存、拦截器、日志 |
二者关系 | Retrofit 依赖 OkHttp | 上层封装 + 底层驱动 |
封装建议 | 单例 + 安全封装 | 统一异常处理与日志管理 |
✨ 结语
Retrofit 与 OkHttp 的组合不仅是 Android 网络层的"黄金搭档",更是大型项目中稳定与扩展性的保证。
通过良好的封装、缓存策略和拦截器管理,我们可以极大地提升网络模块的可维护性与性能表现。