okhttp详解
OkHttp 是 Square 公司开发的一款高效、简洁的 HTTP 客户端库,广泛用于 Android 开发和 Java 后端,支持 HTTP/1.1、HTTP/2、WebSocket 等,以性能优异、易用性强著称。以下从核心特性、工作原理、使用方式等方面详解:
一、核心特性
高效连接复用通过连接池(
ConnectionPool)复用 TCP 连接,减少握手开销(默认保持 5 个空闲连接,超时时间 5 分钟),尤其适合频繁请求的场景。支持 HTTP/2多路复用(单连接并发处理多个请求)、头部压缩(HPACK),大幅提升性能。
拦截器机制提供应用拦截器(
Application Interceptor)和网络拦截器(Network Interceptor),可用于日志打印、请求加密、缓存控制等。自动重试与重定向对某些失败的请求(如连接超时、5xx 状态码)自动重试,支持 HTTP 重定向(3xx 状态码)。
缓存支持基于 HTTP 缓存协议(如
Cache-Control、ETag)实现本地缓存,减少网络请求。异步 / 同步请求支持同步阻塞调用和异步回调(
Callback),适配不同场景。
OkHttp 凭借其高效性和灵活性,成为网络请求的首选库,深入理解其原理和最佳实践能显著提升网络层代码质量。
三、基本使用示例
1. 依赖引入(Android)
gradle
dependencies {implementation 'com.squareup.okhttp3:okhttp:4.12.0' // 最新版本可更新
}
2. 同步 GET 请求
java
运行
OkHttpClient client = new OkHttpClient();String run(String url) throws IOException {Request request = new Request.Builder().url(url).build();try (Response response = client.newCall(request).execute()) {return response.body().string(); // 注意:body() 只能调用一次}
}
3. 异步 POST 请求(带表单参数)
java
运行
OkHttpClient client = new OkHttpClient();void post(String url, String json) {MediaType JSON = MediaType.parse("application/json; charset=utf-8");RequestBody body = RequestBody.create(JSON, json);Request request = new Request.Builder().url(url).post(body).build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {e.printStackTrace();}@Overridepublic void onResponse(Call call, Response response) throws IOException {try (ResponseBody responseBody = response.body()) {if (!response.isSuccessful()) {throw new IOException("Unexpected code " + response);}// 处理响应(注意:Android 中需切换到主线程更新 UI)String result = responseBody.string();}}});
}
四、拦截器使用
拦截器可串联执行,常用于统一处理逻辑:
java
运行
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new LoggingInterceptor()) // 应用拦截器.addNetworkInterceptor(new CacheInterceptor()) // 网络拦截器.build();class LoggingInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();// 打印请求信息Log.d("OkHttp", "Request: " + request.url());// 执行请求Response response = chain.proceed(request);// 打印响应信息Log.d("OkHttp", "Response: " + response.code());return response;}
}
五、注意事项
ResponseBody 处理:body().string() 会消耗流,不可重复调用;大文件建议用 byteStream() 逐步读取。 线程安全:OkHttpClient 是线程安全的,建议全局共享一个实例,避免重复创建。 Android 网络权限:需在 AndroidManifest.xml 中添加 <uses-permission android:name="android.permission.INTERNET" />。 异步回调线程:onResponse 和 onFailure 运行在子线程,更新 UI 需切换到主线程(如用 Handler 或 Coroutine)。
2. 工作流程(以异步请求为例)
构建 OkHttpClient 和 Request 对象。 通过 OkHttpClient.newCall(request) 创建 RealCall(Call 的实现类)。 调用 enqueue(Callback),将任务提交到 Dispatcher(调度器)。 Dispatcher 管理线程池,分配线程执行请求:
- 检查缓存,命中则直接返回缓存响应。
- 未命中则通过
ConnectionPool获取或创建连接。 - 经拦截器链处理(如重试、重定向、网络请求)后获取响应。
响应通过 Callback 回调到主线程(Android 中需配合 Handler)。
二、核心组件与工作流程
1. 核心类
OkHttpClient:客户端实例,配置全局参数(连接超时、拦截器、缓存等),线程安全,建议全局单例。 Request:请求对象,包含 URL、方法(GET/POST)、头信息、请求体等。 Response:响应对象,包含状态码、头信息、响应体(ResponseBody)等。 Call:请求执行的抽象,由 OkHttpClient.newCall(request) 创建,支持 execute()(同步)和 enqueue(Callback)(异步)。 Interceptor:拦截器接口,用于处理请求 / 响应的中间过程。 。
