一、OkHttp3的使用
流程:
同步:
Response response = client.newCall(request).execute();
异步:
client.newCall(request).enqueue(new Callback() {});
1、创建OkHttpClient客户端
a、
OkHttpClient client = new OkHttpClient();
b、
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.connectTimeout(TIMEOUT_CONNECTION, TimeUnit.SECONDS)
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.build();
return chain.proceed(request);
}
})
.build();
2、创建Request请求体
Request request = new Request.Builder()
.url(url)
.build();
3、执行请求
a、同步请求
Response response = client.newCall(request).execute();
b、异步请求
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 {
...
});
二、OkHttp3请求流程
1、创建OkHttpClient客户端;
client...
2、调用newCall方法添加请求体Request;
client.newCall(request)...;
3、newCall方法实际调用RealCall类的newRealCall方法;
@Override
public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
4、执行execute()或者enqueue()方法;
5、拦截器处理;
Response result = getResponseWithInterceptorChain();
6、最后返回请求结果;
三、源码分析
1、创建OkHttpClient客户端
OkHttpClient client = new OkHttpClient();
OkHttpClient构造方法,默认通过Builder创建,此时参数均为默认
public OkHttpClient() {
this(new Builder());
}
Builder模式,初始化OkHttpClient参数
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
...
}
指定具体参数(非默认)时,调用该方法生效
public OkHttpClient build() {
return new OkHttpClient(this);
}
指定具体参数后调用该方法使其生效
OkHttpClient(Builder builder) {
this.dispatcher = builder.dispatcher;
this.proxy = builder.proxy;
...
}
2、Request的创建
Request request = new Request.Builder().url(url).build();
创建方式同OkHttpClient,Builder模式
public Builder() {
this.method = "GET";
this.headers = new Headers.Builder();
}
Builder(Request request) {
this.url = request.url;
this.method = request.method;
...
}
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
...
}
3、OkHttpClient的newCall方法
Response response = client.newCall(request).xxx();
这里的newCall方法具体执行的是RealCall类的newRealCall方法
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
真正创建call的地方
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;
}
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
...
}
4、同步请求execute()
Response response = client.newCall(request).execute();
上一步提到这里的Call具体实现是RealCall类(Call只是个接口),所以这里执行的是RealCall类的execute()方法;
@Override
public Response execute() throws IOException {
synchronized (this) {
// 同步请求只执行一次,被标记为已经执行的不会再执行
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
timeout.enter();
eventListener.callStart(this);
try {
// 由dispatcher将请求放入同步请求队列,这里可以看到执行同步请求并不是立即执行,而是将其放入请求队列,由队列出维护
client.dispatcher().executed(this);
// 拦截器相关处理,最终返回请求结果
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
e = timeoutExit(e);
eventListener.callFailed(this, e);
throw e;
} finally {
// 最终由dispatcher将请求移出请求同步请求队列
client.dispatcher().finished(this);
}
}
添加拦截器,并调用RealInterceptorChain类的proceed方法
Response getResponseWithInterceptorChain() throws IOException {
...
Interceptor.Chain chain = new RealInterceptorChain(interceptors,null,null, null,0,originalRequest,this,eventListener,client.connectTimeoutMillis(),client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
RealInterceptorChain # proceed
@Override
public Response proceed(Request request) throws IOException {
return proceed(request, streamAllocation, httpCodec, connection);
}
真正执行的方法
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec, RealConnection connection) throws IOException {
...
// 实例化下一个拦截器的Chain对象
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec, connection, index + 1, request, call, eventListener, connectTimeout, readTimeout, writeTimeout);
// 拿到当前的拦截器
Interceptor interceptor = interceptors.get(index);
// 调用当前拦截器的intercept方法,并将下一个拦截器的Chain对象传递,直到最后得到response
Response response = interceptor.intercept(next);
...
if (response.body() == null) {
throw new IllegalStateException("interceptor " + interceptor + " returned a response with no body");
}
return response;
}
5、异步请求enqueue()
Response response = client.newCall(request).enqueue();
Call的具体实现类RealCall中:
@Override
public void enqueue(Callback responseCallback) {
// 同理,执行情况标记
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
// 执行Dispatcher的enqueue()方法,将一个异步请求放入异步请求队列
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
Dispatcher# enqueue():
void enqueue(AsyncCall call) {
synchronized (this) {
// 放入准备异步请求队列
readyAsyncCalls.add(call);
}
promoteAndExecute();
}
Dispatcher# promoteAndExecute():
private boolean promoteAndExecute() {
assert (!Thread.holdsLock(this));
List<AsyncCall> executableCalls = new ArrayList<>();
boolean isRunning;
synchronized (this) {
// 逐个从异步请求队列中取出请求
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall asyncCall = i.next();
// 正在运行的队列是否已经达到最大数
if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
// call占用的host小于最大数量
if (runningCallsForHost(asyncCall) >= maxRequestsPerHost) continue; // Host max capacity.
i.remove();
// 将请求添加到可执行队列
executableCalls.add(asyncCall);
// 将请求添加到正在执行的队列
runningAsyncCalls.add(asyncCall);
}
isRunning = runningCallsCount() > 0;
}
for (int i = 0, size = executableCalls.size(); i < size; i++) {
AsyncCall asyncCall = executableCalls.get(i);
// 创建一个线程池,由RealCall中的AsyncCall去执行
asyncCall.executeOn(executorService());
}
return isRunning;
}
AsyncCall类
final class AsyncCall extends NamedRunnable {
...
void executeOn(ExecutorService executorService) {
assert (!Thread.holdsLock(client.dispatcher()));
boolean success = false;
try {
// 由线程池去具体执行异步请求
executorService.execute(this);
success = true;
} catch (RejectedExecutionException e) {
InterruptedIOException ioException = new InterruptedIOException("executor rejected");
ioException.initCause(e);
eventListener.callFailed(RealCall.this, ioException);
responseCallback.onFailure(RealCall.this, ioException);
} finally {
if (!success) {
client.dispatcher().finished(this); // This call is no longer running!
}
}
}
最终执行到这里
@Override
protected void execute() {
boolean signalledCallback = false;
timeout.enter();
try {
// 拦截器相关处理
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this,new IOException("Canceled"));
} else {
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
e = timeoutExit(e);
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
eventListener.callFailed(RealCall.this, e);
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
6、拦截器处理
拦截器处理相关代码
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
// 将创建OkHttpClient对象时设置的拦截器添加进来
interceptors.addAll(client.interceptors());
// 失败重试及重定向,该对象在RealCall构造方法中初始化
interceptors.add(retryAndFollowUpInterceptor);
// 请求时添加必要的Header信息,获取响应时移除必要的Header
interceptors.add(new BridgeInterceptor(client.cookieJar()));
// 缓存相关的拦截器
interceptors.add(new CacheInterceptor(client.internalCache()));
// 网络连接,和服务器连接
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
// 配置 OkHttpClient 时设置的 networkInterceptors
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);
}
网友评论