以get请求为例子:
OkHttpClient client=new OkHttpClient();
Request request=new Request.Builder().url("").build();
Response response=client.newCall(request).execute();
三行代码就可以创建一个请求 , 接下来我们查看具体的代码
OkHttpClient client=new OkHttpClient();
public OkHttpClient() {
this(new Builder());
}
构造方法中再次调用有参的构造方法 , 点进去之后 , 会发现一系列的初始化操作 . 其中我们关心这几个属性 , 先记住名字就好
- dispatcher 分发器
- interceptors 应用层的拦截器
- networkInterceptors 网络层拦截器
Request request=new Request.Builder().url("").build();
其实这里就是一个对象的初始化过程.......不多解释了
Response response=client.newCall(request).execute();
从newCall()方法开始:
@Override public Call newCall(Request request) {
return new RealCall(this, request);
}
直接实例化了另一个类RealCall, 实例化之后 , 回到原来的语句中 , 接下来执行的execute()方法 , 就肯定是在该类中进行的了
这里不要直接点击execute , 会跑偏的= =
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
try {
// 使用分发器来处理
client.dispatcher().executed(this);
// 交由拦截器来处理
Response result = getResponseWithInterceptorChain(false);
if (result == null) throw new IOException("Canceled");
return result;
} finally {
client.dispatcher().finished(this);
}
}
这里主要有两个方法 , 一个分发 , 一个拦截. 我们先看分发器的executed的实现:
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
恩.......比较简单昂 , 就是将请求添加到队列中 , 这里用到队列数据结构. 加入队列之后, 拦截器来进一步处理
private Response getResponseWithInterceptorChain(boolean forWebSocket) throws IOException {
Interceptor.Chain chain = new ApplicationInterceptorChain(0, originalRequest, forWebSocket);
return chain.proceed(originalRequest);
}
首先创建了一个应用层的拦截器ApplicationInterceptorChain , 再调用拦截器的proceed方法 , 获取到请求数据.
先点开ApplicationInterceptorChain , 发现它是一个内部类 , 初始化了一些东西 , 然后接下来的proceed方法也应该在这个类里面了
@Override public Response proceed(Request request) throws IOException {
// If there's another interceptor in the chain, call that.
if (index < client.interceptors().size()) {
Interceptor.Chain chain = new ApplicationInterceptorChain(index + 1, request, forWebSocket);
Interceptor interceptor = client.interceptors().get(index);
Response interceptedResponse = interceptor.intercept(chain);
if (interceptedResponse == null) {
throw new NullPointerException("application interceptor " + interceptor
+ " returned null");
}
return interceptedResponse;
}
// No more interceptors. Do HTTP.
// 开始请求
return getResponse(request, forWebSocket);
}
}
这里先判断了当前拦截器有没有对应的处理 , 没有就新建一个拦截器 , 并执行intercept方法 . 拦截器可以用来转换格式 , 重写请求等......最后 , 反回了真正的请求getResponse()
Response getResponse(Request request, boolean forWebSocket) throws IOException {
// Copy body metadata to the appropriate request headers.
RequestBody body = request.body();
// 拼接请求头
if (body != null) {
Request.Builder requestBuilder = request.newBuilder();
MediaType contentType = body.contentType();
if (contentType != null) {
requestBuilder.header("Content-Type", contentType.toString());
}
long contentLength = body.contentLength();
if (contentLength != -1) {
requestBuilder.header("Content-Length", Long.toString(contentLength));
requestBuilder.removeHeader("Transfer-Encoding");
} else {
requestBuilder.header("Transfer-Encoding", "chunked");
requestBuilder.removeHeader("Content-Length");
}
request = requestBuilder.build();
}
// Create the initial HTTP engine. Retries and redirects need new engine for each attempt.
// 创建HTTP engine, 用于发送和回复的细节处理
engine = new HttpEngine(client, request, false, false, forWebSocket, null, null, null);
int followUpCount = 0;
while (true) {
if (canceled) {
engine.releaseStreamAllocation();
throw new IOException("Canceled");
}
boolean releaseConnection = true;
try {
// 发送请求
engine.sendRequest();
// 读取回复
engine.readResponse();
releaseConnection = false;
} catch (RequestException e) {
// The attempt to interpret the request failed. Give up.
throw e.getCause();
} catch (RouteException e) {
// The attempt to connect via a route failed. The request will not have been sent.
HttpEngine retryEngine = engine.recover(e.getLastConnectException(), true, null);
if (retryEngine != null) {
releaseConnection = false;
engine = retryEngine;
continue;
}
// Give up; recovery is not possible.
throw e.getLastConnectException();
} catch (IOException e) {
// An attempt to communicate with a server failed. The request may have been sent.
HttpEngine retryEngine = engine.recover(e, false, null);
if (retryEngine != null) {
releaseConnection = false;
engine = retryEngine;
continue;
}
// Give up; recovery is not possible.
throw e;
} finally {
// We're throwing an unchecked exception. Release any resources.
if (releaseConnection) {
StreamAllocation streamAllocation = engine.close();
streamAllocation.release();
}
}
Response response = engine.getResponse();
Request followUp = engine.followUpRequest();
if (followUp == null) {
if (!forWebSocket) {
engine.releaseStreamAllocation();
}
return response;
}
StreamAllocation streamAllocation = engine.close();
if (++followUpCount > MAX_FOLLOW_UPS) {
streamAllocation.release();
throw new ProtocolException("Too many follow-up requests: " + followUpCount);
}
if (!engine.sameConnection(followUp.url())) {
streamAllocation.release();
streamAllocation = null;
} else if (streamAllocation.stream() != null) {
throw new IllegalStateException("Closing the body of " + response
+ " didn't close its backing stream. Bad interceptor?");
}
request = followUp;
engine = new HttpEngine(client, request, false, false, forWebSocket, streamAllocation, null,
response);
}
}
首先 , 设置请求头 , 拼接一条完整的请求, 然后初始化HttpEngine用于细节优化 , 再开始请求 , 请求完成后读取请求结果.
- 开始请求部分:
public void sendRequest() throws RequestException, RouteException, IOException {
if (cacheStrategy != null) return; // Already sent.
if (httpStream != null) throw new IllegalStateException();
// 首先 ,对请求头再次做一次处理
Request request = networkRequest(userRequest);
// 获取用户设置的缓存
InternalCache responseCache = Internal.instance.internalCache(client);
// 从缓存中获取之前请求过的Response
Response cacheCandidate = responseCache != null
? responseCache.get(request)
: null;
long now = System.currentTimeMillis();
// 根据请求和缓存结果来设置缓存策略,先从缓存拿,如果超时,那么从网络请求.
cacheStrategy = new CacheStrategy.Factory(now, request, cacheCandidate).get();
networkRequest = cacheStrategy.networkRequest;
cacheResponse = cacheStrategy.cacheResponse;
if (responseCache != null) {
responseCache.trackResponse(cacheStrategy);
}
if (cacheCandidate != null && cacheResponse == null) {
closeQuietly(cacheCandidate.body()); // The cache candidate wasn't applicable. Close it.
}
...
...
try {
// 建立链接, 使用socket创建,可以自动选择偏好链接, 选择连接时,首先从连接池来查找,
// 没有的话使用路径选择器,若还找不到的话就新建一个连接,同时将连接放到连接池中
httpStream = connect();
httpStream.setHttpEngine(this);
if (writeRequestHeadersEagerly()) {
long contentLength = OkHeaders.contentLength(request);
if (bufferRequestBody) {
if (contentLength > Integer.MAX_VALUE) {
throw new IllegalStateException("Use setFixedLengthStreamingMode() or "
+ "setChunkedStreamingMode() for requests larger than 2 GiB.");
}
if (contentLength != -1) {
// Buffer a request body of a known length.
httpStream.writeRequestHeaders(networkRequest);
requestBodyOut = new RetryableSink((int) contentLength);
} else {
// Buffer a request body of an unknown length. Don't write request headers until the
// entire body is ready; otherwise we can't set the Content-Length header correctly.
requestBodyOut = new RetryableSink();
}
} else {
httpStream.writeRequestHeaders(networkRequest);
requestBodyOut = httpStream.createRequestBody(networkRequest, contentLength);
}
}
success = true;
} finally {
// If we're crashing on I/O or otherwise, don't leak the cache body.
if (!success && cacheCandidate != null) {
closeQuietly(cacheCandidate.body());
}
}