OkHttp请求构建:Request、Response、Call的创建与执行流程
聊聊三个核心类
开始之前,我想先帮你理清三个最基础的东西:Request、Response 和 Call。说白了,Request 就是你想表达的请求意图——URL、Header、Body;Response 是服务器给你的回话——状态码、头、实体;而 Call 是连接这两个的“调度员”。
我在项目中遇到很多同事把 Request 和 Call 搞混。嗯,其实记一句就好:你构造 Request,然后用 OkHttpClient 的 newCall 创建 Call,最后由 Call 去执行并返回 Response。就这么简单。
Request 构建:Builder 模式怎么用
OkHttp 的 Request 用了 Builder 模式。我个人习惯这样写:
Request request = new Request.Builder()
.url("https://api.example.com/users")
.header("Authorization", "Bearer token123")
.get()
.build();
你想发 POST 就换成 .post(RequestBody)。注意 Builder 可以链式调用,每个方法回到自身,最后 build() 生成不可变对象。
Call 是什么?你与服务器的“电话线”
Call 代表一次即将执行(或正在执行)的 HTTP 请求。它可以通过 OkHttpClient.newCall(request) 生成。记住,一个 Call 只能被执行一次,重复执行会抛异常。
Call 有两个执行方式:
- 同步:
call.execute(),直接返回 Response,会阻塞当前线程。 - 异步:
call.enqueue(Callback),在内部线程池里跑,回调通知结果。
我曾经写过一段代码,在 Android 主线程里调了 execute(),结果直接 ANR。嗯,网络请求永远不要跑在主线程,除非你明确知道自已在干嘛。
Response:数据拿到了,然后呢?
Response 对象包含:
| 属性 | 说明 | 典型值 |
|---|---|---|
code() | HTTP 状态码 | 200, 404, 500 |
message() | 状态消息 | "OK", "Not Found" |
headers() | 所有响应头 | Content-Type, Date… |
body() | 响应体 | 只能消费一次 |
完整的执行流程
为了让你一眼看明白整个链条,我画了一张流程图。看看它怎么从构造到结束:
实战中容易踩的坑
讲几个我亲自踩过的,给你当避坑指南:
- Cache 过期没用:OkHttp 默认没开缓存。我建议如果你做列表请求,加一个
new OkHttpClient.Builder().cache(cache),能省不少流量。 - Interceptor 误顺序:Application Interceptor 和 Network Interceptor 执行时机不同。我犯过在 Application 层加重试,结果死循环。
- 忘记关闭 Response:这个最要命。现在 Kotlin 里可以用
response.use { … }自动关闭,Java 就老老实实 try-finally。
一个小练习
你可以在自己的项目里试一下:构造一个 GET 请求,用同步方式获取豆瓣 API 的返回。然后打印出 Response 的 code、header 和 body 的前 200 个字符。注意处理好关闭哦。
OkHttpClient client = new OkHttpClient.Builder().build();
Request request = new Request.Builder()
.url("https://api.douban.com/v2/book/1220562")
.build();
Call call = client.newCall(request);
Response response = null;
try {
response = call.execute();
System.out.println("Response code: " + response.code());
System.out.println("Header: " + response.header("Content-Type"));
System.out.println("Body: " + response.body().string().substring(0, 200));
} finally {
if (response != null) response.close();
}
嗯,跑通了的话,你就已经掌握了 OkHttp 最基本的请求构建和执行流程。接下来就是更深度的拦截器、连接池这些话题了——不过那是另一章的事。