1. OkHttp 简介与基本用法
说实话,最早我在做 Android 网络请求时,用的还是 HttpClient 那套老古董。后来换了 OkHttp,感觉世界都清净了。OkHttp 是什么?它就是 Google 官方钦定、 Android 平台上性能最好的 HTTP 客户端库。很多项目里的 Retrofit,底层其实也是它。我自己的习惯是,但凡涉及网络请求,直接上 OkHttp,省心。
1.1 OkHttp 的作用
OkHttp 能帮你做三件事:
- 发起 HTTP/1.1 和 HTTP/2 请求 —— 支持同步和异步。
- 自动管理连接池和复用 —— 减少握手开销,提升速度。
- 支持拦截器链 —— 你可以在请求前后做日志、重试、缓存等操作。
另外,它还内置了 Gzip 解压、失败重试、Cookie 管理等能力。说白了,一个 OkHttpClient 对象,就能搞定 90% 的网络需求。
1.2 核心组件一览
OkHttp 的几个关键角色,我整理成了一张表,方便你对照理解:
| 组件 | 职责 | 备注 |
|---|---|---|
| OkHttpClient | 客户端核心对象,管理连接池、配置、拦截器 | 一般全局单例 |
| Request | 封装 URL、方法、头部、请求体 | 通过 Builder 构建 |
| Call | 代表一次准备执行的请求,可同步或异步 | 由 OkHttpClient 创建 |
| Response | 服务器返回的结果,包含状态码、头部、响应体 | 注意要关闭 body |
| Interceptor | 拦截器,可插拔地处理请求/响应 | 分为应用层和网络层 |
| Cache | 缓存策略,配合 Cache-Control 头实现 | 需配置 Cache 目录 |
我记得刚开始用 OkHttp 时,老把 Call 和 Request 搞混。你只需记住:Request 是“我要什么”,Call 是“我去拿”。
1.3 基本请求/响应流程
下面这张图展示了 OkHttp 内部的工作流程,从创建客户端到获得响应。我在项目里排查网络问题时,经常对着这个流程来定位是哪个环节出了错。
1.4 基本用法 —— 同步与异步请求
上手 OkHttp 最快的方式就是直接写代码。我一直觉得,看十遍文档不如自己跑一次请求。
同步请求
同步请求会阻塞当前线程,不能在主线程执行(Android 上会抛 NetworkOnMainThreadException)。
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
.url("https://api.github.com/repos/square/okhttp")
.get()
.build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
String body = response.body().string();
System.out.println("响应: " + body);
}
// 记得关闭 response.body()
response.close();
} catch (IOException e) {
e.printStackTrace();
}
异步请求
真实项目中我基本都用异步。不需要自己开线程,回调会在 OkHttp 的工作线程中执行。
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.github.com/")
.build();
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 body = response.body().string();
System.out.println("异步结果: " + body);
}
response.close();
}
});
1.5 个人经验与避坑
我曾经在一个线上项目中,因为忘记在 finally 块里关闭 Response,导致连接泄漏,OOM 差点上线。从那以后,我养成习惯:要么用 try-with-resources,要么在回调里立马 close。
另外,OkHttp 默认是支持失败重试的(最多一次)。但如果你用的是异步,重试可能会导致回调被调用多次,这时要小心 UI 更新。我的做法是:在 onResponse 里加一个原子布尔锁,防止重复处理。
- OkHttp 是高性能 HTTP 客户端,核心为 OkHttpClient、Request、Call、Response。
- 请求经过应用拦截器 → 网络拦截器 → 缓存策略 → 返回响应。
- 同步用 execute(),异步用 enqueue()。
- 记得关闭 Response,最好用 try-finally 或 try-with-resources。