OkHttp源码解析
基本使用
val okhttp = OkHttpClient.Builder()
.build()
val request = Request.Builder()
.url("https://www.baidu.com")
.get()
.build()
val call = okhttp.newCall(request)
call.enqueue(object : Callback{
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: Response) {
}
})
- 通过构造者模式创建
OkHttpClient
对象,其中可以设置拦截器等参数,在build()
方法后正式确认赋值 - 通过构造这模式创建
Request
对象,其中可以设置url
等参数,同样通过build()
方法后正式确认赋值 - 通过
newCall
得到Call
对象 - 通过
enqueue
进行异步网络请求
Call对象的获取
/**
* 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 */);
}
Call
为接口类,RealCall.newRealCall
方法中RealCall
为Call
的实现类,调用RealCall
的newRealCall
方法得到Call
对象的实例。
call.enqueue方法
调用RealCall
的enqueue
方法,
@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));
}
通过同步锁操作,禁止enqueue
方法调用2次,否则会抛出异常IllegalStateException
client.dispatcher()
为Dispatcher
类对象的实例。
Dispatcher
private int maxRequests = 64;
private int maxRequestsPerHost = 5;
private @Nullable Runnable idleCallback;
/** Executes calls. Created lazily. */
private @Nullable ExecutorService executorService;
/** Ready async calls in the order they'll be run. */
private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
/** Running asynchronous calls. Includes canceled calls that haven't finished yet. */
private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
/** Running synchronous calls. Includes canceled calls that haven't finished yet. */
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
在Dispatcher
类中,定义了maxRequests
最大请求并发数,maxRequestsPerHost
每台主机的同时最大请求数和3个队列。分别为缓存队列,异步请求队列和同步请求队列。
在调用Dispatcher
的enqueue()
方法时
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
会对队列的长度和最大请求数等进行判断,小于即添加到异步请求队列中,通过线程池executorService().execute(call)
进行执行。
ExecutorService线程池
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
其中线程池设定了核心线程数为0,最大线程数为Integer.MAX_VALUE
,当前线程结束后复用时间为60s,若60s之前则复用,否则有新的请求后要重新创建。参数五为队列,存放当前同时进行的所有请求。参数六为线程工厂为了设定线程名和是否是守护线程。
executorService().execute(call)方法
此方法执行参数的为Runnable
。其中AsyncCall
继承Runnable
,所以执行了AsyncCall
的execute
方法。
@Override protected void execute() {
boolean signalledCallback = false;
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) {
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);
}
}
signalledCallback
参数用于区分错误是OkHttp
还是我们自己代码的错误。若通过responseCallback
的回调,则为true
,catch
异常捕获后则为用户自己的错误。否则未调用回调,则为OkHttp
自己的错误。client.dispatcher().finished(this)
无论结果如何,都会走finally
代码块的finished
方法将其关闭。
getResponseWithInterceptorChain()
Response response = getResponseWithInterceptorChain()
通过getResponseWithInterceptorChain()
获得返回的Response
结果。
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);
}
通过责任链的模式对拦截器的添加。
首先添加自己设定的interceptor
应用拦截器,然后依次执行retryAndFollowUpInterceptor
重定向拦截器、BridgeInterceptor
含有请求头信息的桥接拦截器、CacheInterceptor
缓存拦截器(其中会对数据没有变化的值直接返回)、ConnectInterceptor
、自己设定的networkInterceptors()
网络拦截器,最后为和服务器真正交互的CallServerInterceptor
拦截器。获取服务器数据后同样依次返回Response
。