這段時(shí)間老李的新公司要更換網(wǎng)絡(luò)層,知道現(xiàn)在主流網(wǎng)絡(luò)層的模式是RxJava+Retrofit+OKHttp,所以老李開始研究這三個(gè)項(xiàng)目的源代碼,在更換網(wǎng)絡(luò)層后,開始分享這個(gè)三個(gè)項(xiàng)目源碼的分析。*
本篇文章 主要講解OKHttp源碼解析(3.7.0)
OKHttp官網(wǎng)
github地址
本文大體上分為11個(gè)部分
- 1.OkHttp源碼解析(一):OKHttp初階
- 2 OkHttp源碼解析(二):OkHttp連接的"前戲"——HTTP的那些事
- 3 OkHttp源碼解析(三):OKHttp中階之線程池和消息隊(duì)列
- 4 OkHttp源碼解析(四):OKHttp中階之?dāng)r截器及調(diào)用鏈
- 5 OkHttp源碼解析(五):OKHttp中階之OKio簡(jiǎn)介
- 6 OkHttp源碼解析(六):OKHttp中階之緩存基礎(chǔ)
- 7 OkHttp源碼解析(七):OKHttp中階之緩存機(jī)制
- 8 OkHttp源碼解析(八):OKHttp中階之連接與請(qǐng)求值前奏
- 9 OkHttp源碼解析(九):OKHTTP連接中三個(gè)"核心"RealConnection、ConnectionPool、StreamAllocation
- 10 OkHttp源碼解析(十) OKHTTP中連接與請(qǐng)求
- 11 OkHttp的感謝
本篇文章的主要內(nèi)容如下:
- OkHttp介紹
- OkHttp使用
- OkHttp流程源碼跟蹤
一、OKHTTP簡(jiǎn)介
- 1.支持HTTP2/SPDY
- 2.socket自動(dòng)選擇最好路線,并支持自動(dòng)重連
- 3.擁有自動(dòng)維護(hù)的socket連接池,減少握手次數(shù)
- 4.擁有隊(duì)列線程池,輕松寫并發(fā)
- 5.擁有Interceptors輕松處理請(qǐng)求與響應(yīng)(比如透明GZIP壓縮)基于Headers的緩存策略
二、OKHTTP使用:
1、GET請(qǐng)求
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
2、POST請(qǐng)求
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
三、OKHTTP源碼流程分析
(一)、OKHTTP 同步請(qǐng)求debug代碼跟蹤:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
從上面代碼所示,先是new了一個(gè)OKHttpClient對(duì)象。
1、OKHttpClient類詳解
OKHttpClient類就比較簡(jiǎn)單了:
- 1、里面包含了很多對(duì)象,其實(shí)OKhttp的很多功能模塊都包裝進(jìn)這個(gè)類,讓這個(gè)類單獨(dú)提供對(duì)外的API,這種外觀模式的設(shè)計(jì)十分的優(yōu)雅。外觀模式。
- 2、而內(nèi)部模塊比較多,就使用了Builder模式(建造器模式)。Builder模式(建造器模式)
- 3、它的方法只有一個(gè):newCall.返回一個(gè)Call對(duì)象(一個(gè)準(zhǔn)備好了的可以執(zhí)行和取消的請(qǐng)求)。
而大家仔細(xì)讀源碼又會(huì)發(fā)現(xiàn)構(gòu)造了OKHttpClient后又new了一個(gè)Rquest對(duì)象。那么咱們就來看下Request,說道Request又不得不提Response。所以咱們一起講了
2、Request、Response類詳解
- 1、Request、Response分別抽象成請(qǐng)求和相應(yīng)
- 2、其中Request包括Headers和RequestBody,而RequestBody是abstract的,他的子類是有FormBody (表單提交的)和 MultipartBody(文件上傳),分別對(duì)應(yīng)了兩種不同的MIME類型
FormBody :"application/x-www-form-urlencoded"
MultipartBody:"multipart/"+xxx.- 3、其中Response包括Headers和RequestBody,而ResponseBody是abstract的,所以他的子類也是有兩個(gè):RealResponseBody和CacheResponseBody,分別代表真實(shí)響應(yīng)和緩存響應(yīng)。
- 4、由于RFC協(xié)議規(guī)定,所以所有的頭部信息不是隨便寫的,request的header與response的header的標(biāo)準(zhǔn)都不同。具體的見 List of HTTP header fields。OKHttp的封裝類Request和Response為了應(yīng)用程序編程方便,會(huì)把一些常用的Header信息專門提取出來,作為局部變量。比如contentType,contentLength,code,message,cacheControl,tag...它們其實(shí)都是以name-value對(duì)的形勢(shì),存儲(chǔ)在網(wǎng)絡(luò)請(qǐng)求的頭部信息中。
根據(jù)從上面的GET請(qǐng)求,顯示用builder構(gòu)建了Request對(duì)象,然后執(zhí)行了OKHttpClient.java的newCall方法,那么咱們就看看這個(gè)newCall里面都做什么操作?
/**
* Prepares the {@code request} to be executed at some point in the future.
*/
@Override public Call newCall(Request request) {
return new RealCall(this, request, false /* for web socket */);
}
Call是個(gè)什么東西,那咱們看下Call這個(gè)類
3、Call類詳解
Call: HTTP請(qǐng)求任務(wù)封裝
可以說我們能用到的操縱基本上都定義在這個(gè)接口里面了,所以也可以說這個(gè)類是OKHttp類的核心類了。我們可以通過Call對(duì)象來操作請(qǐng)求了。而Call接口內(nèi)部提供了Factory工廠方法模式(將對(duì)象的創(chuàng)建延遲到工廠類的子類去進(jìn)行,從而實(shí)現(xiàn)動(dòng)態(tài)配置)
Call接口提供了內(nèi)部接口Factory(用于將對(duì)象的創(chuàng)建延遲到該工廠類的子類中進(jìn)行,從而實(shí)現(xiàn)動(dòng)態(tài)的配置).
/**
* A call is a request that has been prepared for execution. A call can be canceled. As this object
* represents a single request/response pair (stream), it cannot be executed twice.
*/
public interface Call extends Cloneable {
/** Returns the original request that initiated this call. */
Request request();
/**
* Invokes the request immediately, and blocks until the response can be processed or is in
* error.
*
* <p>To avoid leaking resources callers should close the {@link Response} which in turn will
* close the underlying {@link ResponseBody}.
*
* <pre>@{code
*
* // ensure the response (and underlying response body) is closed
* try (Response response = client.newCall(request).execute()) {
* ...
* }
*
* }</pre>
*
* <p>The caller may read the response body with the response's {@link Response#body} method. To
* avoid leaking resources callers must {@linkplain ResponseBody close the response body} or the
* Response.
*
* <p>Note that transport-layer success (receiving a HTTP response code, headers and body) does
* not necessarily indicate application-layer success: {@code response} may still indicate an
* unhappy HTTP response code like 404 or 500.
*
* @throws IOException if the request could not be executed due to cancellation, a connectivity
* problem or timeout. Because networks can fail during an exchange, it is possible that the
* remote server accepted the request before the failure.
* @throws IllegalStateException when the call has already been executed.
*/
Response execute() throws IOException;
/**
* Schedules the request to be executed at some point in the future.
*
* <p>The {@link OkHttpClient#dispatcher dispatcher} defines when the request will run: usually
* immediately unless there are several other requests currently being executed.
*
* <p>This client will later call back {@code responseCallback} with either an HTTP response or a
* failure exception.
*
* @throws IllegalStateException when the call has already been executed.
*/
void enqueue(Callback responseCallback);
/** Cancels the request, if possible. Requests that are already complete cannot be canceled. */
void cancel();
/**
* Returns true if this call has been either {@linkplain #execute() executed} or {@linkplain
* #enqueue(Callback) enqueued}. It is an error to execute a call more than once.
*/
boolean isExecuted();
boolean isCanceled();
/**
* Create a new, identical call to this one which can be enqueued or executed even if this call
* has already been.
*/
Call clone();
interface Factory {
Call newCall(Request request);
}
}
在源碼中,OKHttpClient實(shí)現(xiàn)了Call.Factory接口,返回了一個(gè)RealCall對(duì)象。那我們就來看下RealCall這個(gè)類
4、RealCall類詳解
- 1、OkHttpClient的newCall方法里面new了RealCall的對(duì)象,但是RealCall的構(gòu)造函數(shù)需要傳入一個(gè)OKHttpClient對(duì)象和Request對(duì)象(PS:第三個(gè)參數(shù)false表示不是webSokcet).因此RealCall包裝了Request對(duì)象。所以RealCall可以很方便地使用這兩個(gè)對(duì)象。
- 2、RealCall里面的兩個(gè)關(guān)鍵方法是:execute 和 enqueue。分別用于同步和異步得執(zhí)行網(wǎng)絡(luò)請(qǐng)求。
- 3、RealCall還有一個(gè)重要方法是:getResponseWithInterceptorChain,添加攔截器,通過攔截器可以將一個(gè)流式工作分解為可配置的分段流程,既增加了靈活性也實(shí)現(xiàn)了解耦,關(guān)鍵還可以自有配置,非常完美。
所以client.newCall(request).execute();實(shí)際上執(zhí)行的是RealCall的execute方法,現(xiàn)在咱們?cè)倩貋砜聪翿ealCall的execute的具體實(shí)現(xiàn)
@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);
}
}
首先是
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
判斷call是否執(zhí)行過,可以看出每個(gè)Call對(duì)象只能使用一次原則。然后調(diào)用了captureCallStackTrace()方法。
RealCall.java
private void captureCallStackTrace() {
Object callStackTrace = Platform.get().getStackTraceForCloseable("response.body().close()");
retryAndFollowUpInterceptor.setCallStackTrace(callStackTrace);
}
RealCall的captureCallStackTrace() 又調(diào)用了Platform.get().getStackTraceForCloseable()
public class Platform {
public static Platform get() {
return PLATFORM;
}
/**
* Returns an object that holds a stack trace created at the moment this method is executed. This
* should be used specifically for {@link java.io.Closeable} objects and in conjunction with
* {@link #logCloseableLeak(String, Object)}.
*/
public Object getStackTraceForCloseable(String closer) {
if (logger.isLoggable(Level.FINE)) {
return new Throwable(closer); // These are expensive to allocate.
}
return null;
}
}
其實(shí)是調(diào)用AndroidPlatform. getStackTraceForCloseable(String closer)方法。這里就不詳細(xì)說了,后面詳細(xì)說。
然后retryAndFollowUpInterceptor.setCallStackTrace(),在這個(gè)方法里面什么都沒做就是set一個(gè)object進(jìn)去
public final class RetryAndFollowUpInterceptor implements Interceptor {
public void setCallStackTrace(Object callStackTrace) {
this.callStackTrace = callStackTrace;
}
}
綜上所示captureCallStackTrace()這個(gè)方法其實(shí)是捕獲了這個(gè)請(qǐng)求的StackTrace。
然后進(jìn)入了第一個(gè)核心類---Dispatcher的的execute方法了,由于下面是進(jìn)入了關(guān)鍵部分,所以重點(diǎn)講解下,代碼如何:
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} finally {
client.dispatcher().finished(this);
}
看下OKHttpClient的dispatcher()方法的具體內(nèi)容如下圖
//OKHttpClient.java
public Dispatcher dispatcher() {
return dispatcher;
}
大家發(fā)現(xiàn)client.dispatcher()返回的是Dispatcher對(duì)象,那么這個(gè)Dispatcher對(duì)象是何時(shí)創(chuàng)建的那?在OkHttpClient.java里面Build類里面的構(gòu)造函數(shù)里面,如下圖
//OkHttpClient.java
public static final class Builder {
//其它代碼先忽略掉
public Builder() {
dispatcher = new Dispatcher();
//其它代碼先忽略掉
}
}
所以默認(rèn)執(zhí)行Builder()放到時(shí)候就創(chuàng)建了一個(gè)Dispatcher。那么咱們看下dispatcher里面的execute()是如何處理的
/** Used by {@code Call#execute} to signal it is in-flight. */
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
里面發(fā)現(xiàn)是runningSyncCalls執(zhí)行了add方法莫非runningSyncCalls是個(gè)list,咱們查看dispatcher里面怎么定義runningSyncCalls的。
/** 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<>();
原來runningSyncCalls是雙向隊(duì)列啊,突然發(fā)現(xiàn)Dispatcher里面定義了三個(gè)雙向隊(duì)列,看下注釋,我們大概能明白readyAsyncCalls 是一個(gè)存放了等待執(zhí)行任務(wù)Call的雙向隊(duì)列,runningAsyncCalls是一個(gè)存放異步請(qǐng)求任務(wù)Call的雙向任務(wù)隊(duì)列,runningSyncCalls是一個(gè)存放同步請(qǐng)求的雙向隊(duì)列。關(guān)于隊(duì)列咱們?cè)谙缕恼吕锩嬖敿?xì)介紹。
執(zhí)行完client.dispatcher().executed(this);要走到getResponseWithInterceptorChain();方法了里面了,看下這個(gè)方法是具體做什么的?
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
//添加開發(fā)者應(yīng)用層自定義的Interceptor
interceptors.addAll(client.interceptors());
//這個(gè)Interceptor是處理請(qǐng)求失敗的重試,重定向
interceptors.add(retryAndFollowUpInterceptor);
//這個(gè)Interceptor工作是添加一些請(qǐng)求的頭部或其他信息
//并對(duì)返回的Response做一些友好的處理(有一些信息你可能并不需要)
interceptors.add(new BridgeInterceptor(client.cookieJar()));
//這個(gè)Interceptor的職責(zé)是判斷緩存是否存在,讀取緩存,更新緩存等等
interceptors.add(new CacheInterceptor(client.internalCache()));
//這個(gè)Interceptor的職責(zé)是建立客戶端和服務(wù)器的連接
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
//添加開發(fā)者自定義的網(wǎng)絡(luò)層攔截器
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
//一個(gè)包裹這request的chain
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
//把chain傳遞到第一個(gè)Interceptor手中
return chain.proceed(originalRequest);
}
發(fā)現(xiàn) new了一個(gè)ArrayList,然后就是不斷的add,后面 new了 RealInterceptorChain對(duì)象,最后調(diào)用了chain.proceed()方法。先看下RealInterceptorChain的構(gòu)造函數(shù)。
public RealInterceptorChain(List<Interceptor> interceptors, StreamAllocation streamAllocation,
HttpCodec httpCodec, RealConnection connection, int index, Request request) {
this.interceptors = interceptors;
this.connection = connection;
this.streamAllocation = streamAllocation;
this.httpCodec = httpCodec;
this.index = index;
this.request = request;
}
發(fā)現(xiàn)什么都沒做就是做了賦值操作,后面跟蹤下chain.proceed()方法
由于Interceptor是個(gè)接口,所以應(yīng)該是具體實(shí)現(xiàn)類RealInterceptorChain的proceed實(shí)現(xiàn)
public interface Interceptor {
Response intercept(Chain chain) throws IOException;
interface Chain {
Request request();
Response proceed(Request request) throws IOException;
Connection connection();
}
}
public final class RealInterceptorChain implements Interceptor.Chain{
Response intercept(Chain chain) throws IOException;
@Override
public Response proceed(Request request) throws IOException {
return proceed(request, streamAllocation, httpCodec, connection);
}
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
calls++;
// If we already have a stream, confirm that the incoming request will use it.
if (this.httpCodec != null && !this.connection.supportsUrl(request.url())) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must retain the same host and port");
}
// If we already have a stream, confirm that this is the only call to chain.proceed().
if (this.httpCodec != null && calls > 1) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must call proceed() exactly once");
}
// 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);
// Confirm that the next interceptor made its required call to chain.proceed().
if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) {
throw new IllegalStateException("network interceptor " + interceptor
+ " must call proceed() exactly once");
}
// Confirm that the intercepted response isn't null.
if (response == null) {
throw new NullPointerException("interceptor " + interceptor + " returned null");
}
return response;
}
}
由于在構(gòu)造RealInterceptorChain對(duì)象時(shí)候httpCodec直接賦予了null,所以下面代碼直接略過。
// If we already have a stream, confirm that the incoming request will use it.
if (this.httpCodec != null && !this.connection.supportsUrl(request.url())) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must retain the same host and port");
}
// If we already have a stream, confirm that this is the only call to chain.proceed().
if (this.httpCodec != null && calls > 1) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must call proceed() exactly once");
}
然后看到在proceed方面里面又new了一個(gè)RealInterceptorChain類的next對(duì)象,溫馨提示下,里面的streamAllocation, httpCodec, connection都是null,所以這個(gè)next對(duì)象和chain最大的區(qū)別就是index屬性值不同chain是0.而next是1,然后取interceptors下標(biāo)為1的對(duì)象的interceptor。由從上文可知,如果沒有開發(fā)者自定義的Interceptor時(shí),首先調(diào)用的RetryAndFollowUpInterceptor,如果有開發(fā)者自己定義的interceptor則調(diào)用開發(fā)者interceptor。
這里重點(diǎn)說一下,由于后面的interceptor比較多,且涉及的也是重要的部分,而咱們這里主要是講流程,所以這里就不詳細(xì)和大家說了,由后面再詳細(xì)講解,后面的流程是在每一個(gè)interceptor的intercept方法里面都會(huì)調(diào)用chain.proceed()從而調(diào)用下一個(gè)interceptor的intercept(next)方法,這樣就可以實(shí)現(xiàn)遍歷getResponseWithInterceptorChain里面interceptors的item,實(shí)現(xiàn)遍歷循環(huán),縮減后的代碼如下:
//RetryAndFollowUpInterceptor.java
public Response intercept(Chain chain) throws IOException {
//忽略部分代碼
response = ((RealInterceptorChain) chain).proceed(request, streamAllocation, null, null);
//忽略部分代碼
}
//BridgeInterceptor.java
public Response intercept(Chain chain) throws IOException {
//忽略部分代碼
Response networkResponse = chain.proceed(requestBuilder.build());
//忽略部分代碼
}
//CacheInterceptor.java
public Response intercept(Chain chain) throws IOException {
//忽略部分代碼
networkResponse = chain.proceed(networkRequest);
//忽略部分代碼
}
//ConnectInterceptor.java
public Response intercept(Chain chain) throws IOException {
//忽略部分代碼
return realChain.proceed(request, streamAllocation, httpCodec, connection);
}
讀過源碼我們知道getResponseWithInterceptorChain里面interceptors的最后一個(gè)item是CallServerInterceptor.java,最后一個(gè)Interceptor(即CallServerInterceptor)里面是直接返回了response 而不是進(jìn)行繼續(xù)遞歸,具體里面是通過OKio實(shí)現(xiàn)的,具體代碼,等后面再詳細(xì)說明,CallServerInterceptor返回response后返回給上一個(gè)interceptor,一般是開發(fā)者自己定義的networkInterceptor,然后開發(fā)者自己的networkInterceptor把他的response返回給前一個(gè)interceptor,依次以此類推返回給第一個(gè)interceptor,這時(shí)候又回到了realCall里面的execute()里面了,代碼如下:
@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);
}
}
最后把response返回給get請(qǐng)求的返回值。至此整體GET請(qǐng)求的大體流程就已經(jīng)結(jié)束了。(PS:最后別忘記走client.dispatcher().finished(this))
大體流程如下圖:
(二)、OKHTTP 異步請(qǐng)求debug代碼跟蹤:
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
前面和同步一樣new了一個(gè)OKHttp和Request。這塊和同步一樣就不說了,那么說說和同步不一樣的地方,后面異步進(jìn)入enqueue()方法
//RealCall.java
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
由于executed默認(rèn)為false,所以先進(jìn)行判斷是否為true,為true則直接跑異常,沒有則設(shè)置為true,可以看出executed這個(gè)是一個(gè)標(biāo)志,標(biāo)志這個(gè)請(qǐng)求是否已經(jīng)正在請(qǐng)求中,合同步一樣先調(diào)用了captureCallStackTrace();然后調(diào)用 client.dispatcher().enqueue(new AsyncCall(responseCallback));client.dispatcher()返回的是Dispatcher對(duì)象所以實(shí)際調(diào)用的是Dispatcher的enqueue(),那么咱們進(jìn)入源碼看下
//Dispatcher.java
private int maxRequests = 64;
private int maxRequestsPerHost = 5;
synchronized void enqueue(AsyncCall call) {
//如果正在執(zhí)行的請(qǐng)求小于設(shè)定值即64,并且請(qǐng)求同一個(gè)主機(jī)的request小于設(shè)定值即5
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
//添加到執(zhí)行隊(duì)列,開始執(zhí)行請(qǐng)求
runningAsyncCalls.add(call);
//獲得當(dāng)前線程池,沒有則創(chuàng)建一個(gè)
executorService().execute(call);
} else {
//添加到等待隊(duì)列中
readyAsyncCalls.add(call);
}
}
根據(jù)源碼和注釋大家可以看到如果正在執(zhí)行的異步請(qǐng)求小于64,并且請(qǐng)求同一個(gè)主機(jī)小于5的時(shí)候就先往正在運(yùn)行的隊(duì)列里面添加這個(gè)call,然后用線程池去執(zhí)行這個(gè)call,否則就把他放到等待隊(duì)列里面。執(zhí)行這個(gè)call的時(shí)候,自然會(huì)去走到這個(gè)call的run方法,那么咱們看下AsyncCall.java這個(gè)類,而AsyncCall.java又繼承自NamedRunnable.java咱們就一起看下他們的源碼
public abstract class NamedRunnable implements Runnable {
protected final String name;
public NamedRunnable(String format, Object... args) {
this.name = Util.format(format, args);
}
@Override public final void run() {
String oldName = Thread.currentThread().getName();
Thread.currentThread().setName(name);
try {
execute();
} finally {
Thread.currentThread().setName(oldName);
}
}
protected abstract void execute();
}
final class AsyncCall extends NamedRunnable {
private final Callback responseCallback;
AsyncCall(Callback responseCallback) {
super("OkHttp %s", redactedUrl());
this.responseCallback = responseCallback;
}
String host() {
return originalRequest.url().host();
}
Request request() {
return originalRequest;
}
RealCall get() {
return RealCall.this;
}
@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);
}
}
}
上面看到NamedRunnable的構(gòu)造方法設(shè)置了name在的run方法里面設(shè)定為當(dāng)前線程的name,而NamedRunnable的run方法里面調(diào)用了它自己的抽象方法execute,由此可見NamedRunnable的作用就是設(shè)置了線程的name,然后回調(diào)子類的execute方法,那么我們來看下AsyncCall的execute方法。貌似好像又回到了之前同步的getResponseWithInterceptorChain()里面,根據(jù)返回的response來這只callback回調(diào)。所以我們得到了OKHTTP的大體流程,如下圖:
三、OKHTTP類詳解
大體核心類主要下圖:
最后給大家看一下整體的流程圖