Okhttp源碼主要涉及到的到有以下幾個類
OKHttpClient
Request
Response
Call
Callback
簡單用法
OkHttpClient client = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url("https://www.baidu.com").build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.body()!=null) {
String body = response.body().string();
}
}
});
分析: 當client.newCall(request)的時候
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
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;
}
RealCall是Call的實現類,所以執行Call的方法其實都是在RealCall中實現的
再來分析call.enqueue()
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");//防止一個call執行二次
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
從上面代碼可以看出,最後是將Callback封裝到了AsyncCall裏面,並將其放到到dispatcher分發器的執行,看Dispathcher的方法
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
AsyncCall是什麼
AsyncCall是RealCall的一個內部類,繼承於
NamedRunnable,面NamedRunnable實現了Runnable,
所以AsyncCall就是一個Runnable
每當線程池執行AsyncCall這個任務時,就會執行其的run方法也就是NameRunnable的一個抽象方法
execute();由子類AsyncCall來實現的,也就是下面代碼
@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);
}
}
這裏有個finally運用的是非常的巧妙,不管成功還是失敗都會執行,下面代碼可以看也,每當一個任務執行完會進行一些判斷,並從隊列中取任務並繼續執行下去.
private void promoteCalls() {
if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall call = i.next();
if (runningCallsForHost(call) < maxRequestsPerHost) {
i.remove();
runningAsyncCalls.add(call);
executorService().execute(call);
}
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}