定義:Okhttp是對Socket的封裝。有三個(gè)主要的類喳挑,Request彬伦,Response,Call
默認(rèn)使用new OkHttpClient() 創(chuàng)建初client對象伊诵。
如果需要初始化網(wǎng)絡(luò)請求的參數(shù)单绑,如timeout,interceptor等,可以創(chuàng)建Builder曹宴,通過builder.build() 創(chuàng)建初client對象搂橙。
三個(gè)問題
1.請求發(fā)送到什么哪去了?框架里放到哪里了笛坦?
請求通過execute方法發(fā)送到框架中的兩個(gè)隊(duì)列中去了:運(yùn)行中的隊(duì)列区转;等待中的隊(duì)列,如果說運(yùn)行中的隊(duì)列總數(shù)小于64并且訪問同一目標(biāo)機(jī)器請求小于5版扩,就進(jìn)入運(yùn)行隊(duì)列废离,否則進(jìn)入等待隊(duì)列
2.請求被誰處理:請求提交到運(yùn)行中隊(duì)列后,交給線程池來處理礁芦,直接處理請求
3.請求是怎么被維護(hù)的:每次請求完成后蜻韭,client.dispath調(diào)用finished方法,對運(yùn)行中的隊(duì)列和等待中的隊(duì)列進(jìn)行數(shù)據(jù)處理柿扣,(在符合條件的情況下肖方,將等待中的加入到運(yùn)行中隊(duì)列中去)
流程
1.通過
生成一個(gè)OkHttpClient client = new OkHttpClient();
2.構(gòu)建一個(gè)Request requet = new Request.Builder()
.get().url("https:www.baidu.com").build();
3.通過client.newCall(request)得到Call,這個(gè)call是他的子類RealCall
4.通過call.execute(同步) 或call.enqueue(異步)啟動(dòng)
A:執(zhí)行Execute
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Execu
ted"); // (1)
executed = true;
}
try { client.dispatcher().executed(this);
// (2)
Response result = getResponseWithInterceptorChain();
// (3)
if (result == null) throw new IOException("Canceled");
return result;
} finally {
client.dispatcher().finished(this); // (4)
} }
1.先判斷這個(gè)call是否被執(zhí)行了,每個(gè)call只能被執(zhí)行一次未状,如果要一個(gè)完成一樣的call可以利用call的clone方法進(jìn)行克隆
2.利用client.dispathcer().execute(this)來進(jìn)行執(zhí)行,其中dispatcher.execute方法為
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
這里我剛開始沒有相同窥妇,之后他加入隊(duì)列后怎么調(diào)用的,后來發(fā)現(xiàn)在 下一個(gè)方法調(diào)用的
3.調(diào)用getResponseWithInterceptorChain函數(shù)來獲取HTTP返回的結(jié)果,這里的originalRequest就是我們的請求剛剛加入隊(duì)列的是RealCall娩践,通過chain.proceed(originalRequest)去調(diào)用
private 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 (!retryAndFollowUpInterceptor.isForWebSocket()) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(
retryAndFollowUpInterceptor.isForWebSocket()));
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
4.最后還要通知dispathcer自己已經(jīng)執(zhí)行完畢
client.dispatcher().finished(this);
會(huì)執(zhí)行finished(隊(duì)列活翩、call,true)
其中這個(gè)方法是同步和異步都調(diào)用的方法,通過第三個(gè)參數(shù)翻伺,是否執(zhí)行promoteCall方法具體的執(zhí)行會(huì)不同材泄,promoteCall方法
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
//TODO calls 移除隊(duì)列
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
//TODO 檢查是否為異步請求,檢查等候的隊(duì)列 readyAsyncCalls吨岭,如果存在等候隊(duì)列拉宗,則將等候隊(duì)列加入執(zhí)行隊(duì)列
if (promoteCalls) promoteCalls();
//TODO 運(yùn)行隊(duì)列的數(shù)量
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
//閑置調(diào)用
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
private void promoteCalls() {
//TODO 檢查 運(yùn)行隊(duì)列 與 等待隊(duì)列
if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
//TODO 將等待隊(duì)列加入到運(yùn)行隊(duì)列中
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall call = i.next();
//TODO 相同host的請求沒有達(dá)到最大,加入運(yùn)行隊(duì)列
if (runningCallsForHost(call) < maxRequestsPerHost) {
i.remove();
runningAsyncCalls.add(call);
executorService().execute(call);
}
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}
B執(zhí)行Enqueue
// RealCall.java
@Override public void enqueue(Callback responseCallback) {
synchronized (this) { // 如果這個(gè) call 已經(jīng)被執(zhí)行過,拋異常
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
//TODO 執(zhí)行異步請求
synchronized void enqueue(AsyncCall call) {
//TODO 同時(shí)請求不能超過并發(fā)數(shù)(64,可配置調(diào)度器調(diào)整)
//TODO okhttp會(huì)使用共享主機(jī)即 地址相同的會(huì)共享socket
//TODO 同一個(gè)host最多允許5條線程通知執(zhí)行請求
if (runningAsyncCalls.size() < maxRequests &&
runningCallsForHost(call) < maxRequestsPerHost) {
//TODO 加入運(yùn)行隊(duì)列 并交給線程池執(zhí)行
runningAsyncCalls.add(call);
//TODO AsyncCall 是一個(gè)runnable旦事,放到線程池中去執(zhí)行魁巩,查看其execute實(shí)現(xiàn)
executorService().execute(call);
} else {
//TODO 加入等候隊(duì)列
readyAsyncCalls.add(call);
}
}