目录
一、OKHttp 的基本使用
1. 添加依赖
2. 发起 HTTP 请求
3. 拦截器(Interceptor)
4. 高级配置
二、OKHttp 核心原理
1. 责任链模式(Interceptor Chain)
2. 连接池(ConnectionPool)
3. 请求调度(Dispatcher)
4. 缓存机制
5. 其他特性
三、拦截器工作原理
3.1 拦截器链的执行顺序
3.2 五大拦截器的工作原理
3.3 拦截器协作流程图
3.4 关键场景分析
3.5 总结
四、常见问题与优化
五、总结
OKHttp 是一款高效的 HTTP 客户端库,由 Square 公司开发,支持 Android 和 Java 应用。它简化了 HTTP 请求处理,支持同步/异步请求、连接池、缓存、拦截器等特性。以下是其使用流程图和原理的详细解析:
一、OKHttp 的基本使用
1. 添加依赖
在 Gradle 中添加依赖:
implementation 'com.squareup.okhttp3:okhttp:4.9.3' // 最新版本以官方为准
2. 发起 HTTP 请求
同步请求示例:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.example.com/data")
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
String responseData = response.body().string();
System.out.println(responseData);
}
} catch (IOException e) {
e.printStackTrace();
}
注意: 同步请求需在子线程执行(Android 中主线程禁止网络操作)。
异步请求示例:
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String responseData = response.body().string();
// 注意:回调在后台线程,需切换线程更新 UI
}
}
});
3. 拦截器(Interceptor)
拦截器用于监控、修改请求和响应。例如添加统一请求头:
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request newRequest = originalRequest.newBuilder()
.header("Authorization", "Bearer token")
.build();
return chain.proceed(newRequest);
}
})
.build();
4. 高级配置
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS) // 连接超时
.readTimeout(30, TimeUnit.SECONDS) // 读取超时
.writeTimeout(30, TimeUnit.SECONDS) // 写入超时
.cookieJar(new CookieJar() { // Cookie 管理
private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url, cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
return cookieStore.getOrDefault(url, new ArrayList<>());
}
})
.build();
二、OKHttp 核心原理
1. 责任链模式(Interceptor Chain)
OKHttp 的核心是 拦截器链,每个请求会依次经过多个拦截器处理:
-
自定义拦截器:开发者添加的拦截器,最先执行。
-
RetryAndFollowUpInterceptor:处理重定向和失败重试。
-
BridgeInterceptor:补全请求头(如
Content-Type
、Cookie
)。 -
CacheInterceptor:根据缓存策略返回缓存或请求网络。
-
ConnectInterceptor:建立与服务器的连接(复用连接池中的连接)。
-
CallServerInterceptor:向服务器发送请求并读取响应。
2. 连接池(ConnectionPool)
-
作用:复用 TCP 连接,减少握手开销。
-
默认配置:最大空闲连接数 5,存活时间 5 分钟。
-
实现:通过
RealConnectionPool
管理空闲连接,清理过期连接。
3. 请求调度(Dispatcher)
-
同步请求:直接执行,但需开发者自行管理线程。
-
异步请求:通过
Dispatcher
管理线程池,默认最大并发请求数 64,单个域名最大并发 5。
4. 缓存机制
-
基于 HTTP 缓存协议(如
Cache-Control
、ETag
)。 -
缓存目录需开发者指定,通过
Cache
类配置:Cache cache = new Cache(context.getCacheDir(), 10 * 1024 * 1024); // 10MB 缓存 OkHttpClient client = new OkHttpClient.Builder().cache(cache).build();
5. 其他特性
-
HTTP/2 支持:多路复用、头部压缩。
-
WebSocket:通过
okhttp-ws
模块支持长连接。 -
HTTPS:支持 TLS 1.3,可配置证书校验策略。
三、拦截器工作原理
OKHttp 的五大核心拦截器构成了其高效的网络请求处理链,每个拦截器职责明确,协同工作。以下是它们的详细工作流程和原理:
3.1 拦截器链的执行顺序
OKHttp 的请求处理基于责任链模式,五大核心拦截器按固定顺序依次处理请求和响应:请求从第一个拦截器进入,逐步传递到最后一个拦截器(CallServerInterceptor
),响应则逆向返回。
3.2 五大拦截器的工作原理
1. RetryAndFollowUpInterceptor
核心职责:处理请求失败的重试与重定向。
-
重试机制:
若请求因网络问题(如连接超时、IO 异常)失败,根据配置决定是否重试(默认最多 20 次)。 -
重定向处理:
若服务器返回 3xx 状态码(如 302 临时跳转),自动构建新请求并重新发起。 -
流程示例:
Request → RetryAndFollowUpInterceptor → 发送请求 → 失败 → 判断是否重试 → 重新执行链 Response ← 处理重定向 → 生成新 Request → 重新执行链
2. BridgeInterceptor
核心职责:桥接应用代码与网络请求,补充请求头、处理 Cookie 和响应编码。
-
请求头补充:
自动添加User-Agent
、Host
、Content-Type
等头信息。
若请求体为RequestBody
,自动计算Content-Length
。 -
Cookie 管理:
通过CookieJar
读取请求对应的 Cookie,写入Cookie
头;保存响应中的Set-Cookie
。 -
响应解码:
若响应头包含Content-Encoding: gzip
,自动解压响应体。
3. CacheInterceptor
核心职责:根据缓存策略管理本地缓存,减少重复请求。
-
缓存命中逻辑:
-
根据请求生成缓存 Key,检查本地是否有有效缓存。
-
若缓存未过期且有效(如
Cache-Control: max-age=3600
),直接返回缓存响应,不再执行后续拦截器。
-
-
缓存更新逻辑:
-
若缓存过期或需要验证(如
Cache-Control: no-cache
),添加条件头(如If-Modified-Since
)发起请求。 -
若服务器返回 304 Not Modified,更新缓存元数据并返回缓存响应。
-
若服务器返回新数据,写入缓存。
-
-
4. ConnectInterceptor
核心职责:建立与服务器的 TCP/TLS 连接,复用连接池。
-
连接复用机制:
-
根据请求的 URL、代理配置等生成连接标识(
Address
)。 -
从连接池(
ConnectionPool
)中查找可用连接,若存在则复用。 -
若无可用连接,创建新连接并加入连接池。
-
-
连接释放:
请求完成后,连接被标记为空闲,连接池根据策略(默认最大空闲连接数 5,存活时间 5 分钟)清理过期连接。
5. CallServerInterceptor
核心职责:执行实际的网络 I/O 操作,发送请求并读取响应。
-
请求发送:
-
将请求头写入网络流。
-
若有请求体(如 POST 数据),分块写入流。
-
-
响应接收:
-
读取响应头(如状态码、Content-Type)。
-
读取响应体,支持分块传输(
Transfer-Encoding: chunked
)。
-
-
资源管理:
确保请求和响应流正确关闭,异常时释放连接。
3.3 拦截器协作流程图
请求发起 → RetryAndFollowUpInterceptor(重试/重定向)
↓
BridgeInterceptor(补全请求头)
↓
CacheInterceptor(查询缓存)
↓
ConnectInterceptor(建立连接)
↓
CallServerInterceptor(发送请求)
响应返回 ← CallServerInterceptor(读取响应)
↑
ConnectInterceptor(释放连接)
↑
CacheInterceptor(更新缓存)
↑
BridgeInterceptor(解压响应)
↑
RetryAndFollowUpInterceptor(处理最终结果)
3.4 关键场景分析
场景 1:缓存命中
-
请求到达
CacheInterceptor
,发现有效缓存。 -
直接返回缓存响应,后续拦截器(如
ConnectInterceptor
)不再执行。 -
节省网络开销,提升响应速度。
场景 2:重定向处理
-
CallServerInterceptor
收到 302 响应。 -
响应返回到
RetryAndFollowUpInterceptor
,生成新请求。 -
重新执行整个拦截器链,直到成功或超出重试次数。
3.5 总结
OKHttp 通过五大拦截器的分工协作,实现了高效、灵活的网络请求处理:
-
RetryAndFollowUpInterceptor:保障请求的可靠性。
-
BridgeInterceptor:简化开发,自动处理协议细节。
-
CacheInterceptor:优化性能,减少重复请求。
-
ConnectInterceptor:从连接池中复用已有连接,跳过 TCP/TLS 握手,降低延迟。。
-
CallServerInterceptor:完成最终的网络 I/O。
理解拦截器链的流程,有助于开发者定制拦截器(如日志打印、加密)或优化网络行为(如缓存策略、连接池配置)。
四、常见问题与优化
-
内存泄漏
-
确保
Callback
或Call
在 Activity/Fragment 销毁时取消:private Call call; call = client.newCall(request); call.enqueue(callback); // 在 onDestroy() 中取消 if (call != null) call.cancel();
-
-
全局配置
-
推荐将
OkHttpClient
实例化为单例,避免重复创建连接池。
-
-
自定义 DNS
-
替换默认 DNS 以优化解析:
client = new OkHttpClient.Builder() .dns(hostname -> { // 自定义 DNS 解析逻辑 return InetAddress.getAllByName(hostname); }) .build();
-
五、总结
OKHttp 的优势:
-
高效:连接池、HTTP/2 支持、缓存机制。
-
灵活:拦截器链可深度定制请求流程。
-
易用:简洁的 API 设计,支持同步/异步调用。
适用场景:移动端 API 调用、文件下载/上传、需要精细控制网络行为的场景。
通过理解其原理,开发者能更好地优化网络层设计(如统一日志、请求加密、性能监控),并高效解决实际问题。