最近打算将 最经常使用的 三个开源框架 Okhttp + Retrofit + Rxjava2 流程分析清楚, 写文章记录下来,也算是对自己思路的一个整理过程.
Okhttp Wiki 地址
一.okhttp的基本使用方法:
//1
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
//2
Request request = new Request.Builder()
.url(url)
.build();
//3
Response response = client.newCall(request).execute();
return response.body().string();
}
- OkHttpClient 实现了 Call.Factory ,Call 负责执行请求和读取响应结果
- Request 是 Http 请求 (An HTTP request.)
- 通过 Call 对象 执行 Http请求, 并获取 Response , Response 是Http 请求的响应
(An HTTP response)
二: 创建 OkhttpClient 对象:
OkHttpClient client = new OkHttpClient();
public OkHttpClient() {
this(new Builder());
}
调用了自身的 OkHttpClient(Builder builder) 构造函数,如果我们外界没有配置的话,就全部使用默认参数
OkHttpClient(Builder builder) {
//默认参数赋值
this.dispatcher = builder.dispatcher;
this.proxy = builder.proxy;
this.protocols = builder.protocols;
this.connectionSpecs = builder.connectionSpecs;
...
}
三: 创建 Http 请求
Request request = new Request.Builder().build();
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
1.判断 请求的 url 是否 为 null, 为null 则直接抛出异常
2.返回一个 Request 对象
Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers.build();
this.body = builder.body;
this.tags = Util.immutableMap(builder.tags);
}
在该构造函数内对 一个 Http 请求 的 url, method ,headers,body 进行赋值
public Builder() {
// 默认的请求方法
this.method = "GET";
this.headers = new Headers.Builder();
}
四: 执行Http 请求
Response response = client.newCall(request).execute();
从使用方法看,我们知道请求是在 OkhttpClient 对象内调用了 newCall
我们先看下 OkhttpClient 里面的newCall 方法:
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
真正的Call 对象是通过 RealCall.newRealCall返回的.
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// Safely publish the Call instance to the EventListener.
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.eventListener = client.eventListenerFactory().create(call);
return call;
}
我们看下 execute() 方法, RealCall 的 excut() 方法 是真正去执行请求的地方:
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed"); //1
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
try {
client.dispatcher().executed(this); //2
Response result = getResponseWithInterceptorChain(); //3
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this); //4
}
}
这里面主要做了 几件事:
- 判断 Call 是否已经被执行
- client.dispatcher() 记录该Call 被执行
/** Used by {@code Call#execute} to signal it is in-flight. */
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
- 通过拦截器链获取响应结果
getResponseWithInterceptorChain 是真正执行 Http 请求,解析Resonse 的地方
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
- client.dispatcher() 执行 finished 方法,将Call 从 runningSyncCalls 移除
/** Used by {@code Call#execute} to signal completion. */
void finished(RealCall call) {
finished(runningSyncCalls, call, false);
}
五. 具体看下 getResponseWithInterceptorChain 是如何执行请求,解析 响应信息的
...未完待续
网友评论