對okhttp的源碼進行了閱讀,主要是學(xué)習(xí)大神的寫作思路吠冤。
官網(wǎng)上面的okhttp的例子浑彰,我們通過例子下手,來看源碼拯辙。
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
一郭变、 沒別的,首頁就是OkHttpClient這個類涯保,這個類里面東西很多诉濒,作者用了建造者模式(Builder Pattern)。當(dāng)然在例子里面看不出來夕春,但是未荒,作者在類的注釋里面給了范例。
// The singleton HTTP client.
public final OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new HttpLoggingInterceptor())
.cache(new Cache(cacheDir, cacheSize))
.build();
二及志、Request同樣也是使用了建造者模式片排,這里面主要就請求的url,參數(shù)速侈,請求頭率寡,請求體的設(shè)置。
final HttpUrl url;
final String method;
final Headers headers;
final RequestBody body;
final Object tag;
三倚搬、 Response response = client.newCall(request).execute();
對于網(wǎng)絡(luò)請求冶共,出現(xiàn)在Call這個接口里面,而RealCall是具體的實現(xiàn)類每界,所以我們重點看RealCall這個類捅僵。
官方給的實例里面,調(diào)用了execute的方法眨层,這個是同步請求庙楚,還有異步的請求enqueue方法。
- 同步的請求趴樱,直接返回了Response
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} finally {
client.dispatcher().finished(this);
}
}
2.異步請求需要AsyncCall回調(diào)
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
在AsyncCall里面調(diào)用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 {
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
}
- 不管是同步還是異步馒闷,都會出現(xiàn)getResponseWithInterceptorChain()這個方法。這個okhttp的核心業(yè)務(wù)伊佃。
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
//重定向攔截器
interceptors.add(retryAndFollowUpInterceptor);
//對request進行重新封裝以及對返回的response進行處理到用戶可以使用
interceptors.add(new BridgeInterceptor(client.cookieJar()));
//緩存攔截器
interceptors.add(new CacheInterceptor(client.internalCache()));
//socket建立連接
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
//數(shù)據(jù)流進行讀寫
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
這個是一個攔截器列表窜司, 每個攔截器有自己的作用,調(diào)用chain.proceed(originalRequest)方法航揉,這里面使用了遞歸
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(
interceptors, streamAllocation, httpCodec, connection, index + 1, request);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
在每個攔截器里面的intercept方法里面調(diào)用chain.proceed(originalRequest)塞祈。