简介
OKHttp3是支持http1和http2网络协议的java和Android网络SDK,OKHttp依赖OKIO。
组成部分
1、OKHttpClient
OKHttpClient类组合了多个对象,实现Call.Factory接口,提供一个newCall方法,返回realcall(call的具体实现类),使用OKHttpClient最好创建一个单例,因为每一个client都有自己的一个连接池connection pool和一个线程池thread pool,重用这些连接池和线程池,可以减少延迟和节省内存。
/**
* Prepares the {@code request} to be executed at some point in the future.
*/
@Override
public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
2、Dispatcher
可以理解为一个策略,调用newcall的时候,不断的从RequestQueue中取出请求;
调用同步方法,直接返回Response,代码如下:
@Override
public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this);
}
}
调用异步方法,把当前请求添加到请求队列,并通过回调的方式返回结果,代码如下:
@Override
public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
当call.enqueue时候,也就是调用dispatcher.enqueue,值得注意的是,dispatcher.enqueue方法中,当前异步请求队列数量小于最大数量64,且同一host请求数量小于5,则把请求加入运行队列,交由线程池来解决,否在放入等待队列,代码如下:
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
3、interceptor
是OKHttp核心类,把网络请求、缓存、压缩等功能统一起来,每一个功能都是一个interceptor,再连成一个interceptor.chain,完成一个网络请求,代码如下:
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);
}
流程图
总结
1、通过OKHttpClient创建一个call,发送同步或者异步请求;
2、OKHttp通过dispatcher对所有的realcall(call的具体实现类)进行统一管理并请求进行处理;
3、execute()和enqueue()最终都会调用到realcall的getResponseWithInterceptorChain(),从拦截器中获取结果;
4、拦截器中,依次通过责任链模式调用RetryAndFollowUpInterceptor(重定向拦截器)、BridgeInterceptor(桥拦截器)、cacheInterceptor(缓存拦截器)、ConnectInterceptor(连接拦截器)、CallServerInterceptor(网络拦截器),对请求依次处理,取得返回结果。