OkHttp 原理与源码解读
核心概述
OkHttp 是 Square 开源的高性能 HTTP 客户端,提供连接池、透明压缩、缓存与 WebSocket 支持。其设计重点在于通过拦截器链与连接复用实现稳定且高效的网络通信。
模块与架构
- 拦截器链:
RealInterceptorChain串联用户、重试、桥接、缓存、连接、网络拦截器等节点。 - 连接管理:
ConnectionPool维护持久连接,结合 HTTP/2 多路复用降低握手成本。 - 调度中心:
Dispatcher管理同步/异步请求队列与线程池。 - 缓存体系:支持内存 + 磁盘缓存,标准遵循 RFC 7234。
- 事件监听:
EventListener提供关键阶段回调,便于埋点与调试。
请求执行流程
- 构建
OkHttpClient并调用newCall(request)返回RealCall。 RealCall.enqueue提交到Dispatcher线程池;execute则阻塞当前线程。RealCall通过RealInterceptorChain.proceed触发拦截器依次执行。ConnectInterceptor负责从连接池获取或新建RealConnection。CallServerInterceptor最终与服务器读写数据,得到Response。
java
// 拦截器链核心片段,展示链式调用流程
public Response proceed(Request request, StreamAllocation allocation, HttpCodec codec, RealConnection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec, connection, index + 1, request);
Interceptor interceptor = interceptors.get(index);
// 每个拦截器负责处理自身逻辑,并调用 next.proceed 进入下一个
Response response = interceptor.intercept(next);
return response;
}关键源码细节
- 连接池:默认最大闲置连接 5 条、保持 5 分钟,可通过
ConnectionPool自定义;利用cleanupRunnable定时回收。 - HTTP/2:
RealConnection在握手后构建Http2Connection,通过 Stream 分发请求,多路复用减轻阻塞。 - 超时控制:
OkHttpClient对连接、读、写分别提供超时;CallTimeoutInterceptor保障整体耗时边界。 - 缓存实现:
Cache基于DiskLruCache,遵循响应头策略;通过CacheStrategy决定命中、条件请求或回源。
常见扩展
- 自定义拦截器实现统一 Header、签名、限流或离线缓存策略。
- 通过
EventListener.Factory采集 DNS、连接、请求、响应等阶段耗时。 - 配合
MockWebServer进行集成测试,验证弱网重试与缓存控制。
风险与优化建议
- 资源释放:确保
ResponseBody在使用后关闭,否则连接无法回收。 - 线程安全:拦截器需无状态或自行同步;避免在拦截器中执行耗时阻塞操作。
- 证书管理:HTTPS 场景下关注证书锁定(Pinning)与自签证书信任链配置。
调试方法
- 启用
HttpLoggingInterceptor或EventListener输出详细日志。 - 使用
setProxy+ Charles/Fiddler 进行抓包分析。 - 结合
StrictMode检测主线程网络调用,保障响应性。