### 前言 前面我們講了 [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源碼解析(1)-OkHttpClient分析](https://www.jianshu.com/p/bf1d01b79ce7) [Okhttp3源碼 ...
### 前言 前面我們講了 [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源碼解析(1)-OkHttpClient分析](https://www.jianshu.com/p/bf1d01b79ce7) [Okhttp3源碼解析(2)-Request分析](https://www.jianshu.com/p/5a85345c8ea7) ### newCall分析 ##### Call初始化 我們首先看一下在哪用到了Call: ``` final Call call = okHttpClient.newCall(request); ``` 想起來了吧?無論是get還是post請求 都要生成call對象,在上面我們發現call實例需要一個`okHttpClient`與`request`實例 ,我們先點進Call類去看看: ``` public interface Call extends Cloneable { //請求 Request request(); //同步 Response execute() throws IOException; //非同步 void enqueue(Callback responseCallback); //取消請求 void cancel(); //是否在請求過程中 boolean isExecuted(); //是否取消 boolean isCanceled(); Call clone(); //工廠介面 interface Factory { Call newCall(Request request); } } ``` 我們發現Call是個介面, 並定義了一些方方法(方法含義在註釋上)。 我們繼續看`newCal()`方法 ``` @Override public Call newCall(Request request) { return RealCall.newRealCall(this, request, false /* for web socket */); } ``` 繼續點擊`newRealCall()`去: ``` private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) { this.client = client; this.originalRequest = originalRequest; this.forWebSocket = forWebSocket; this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket); } 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; } ``` 從代碼中我們發現在`newRealCall()`中初始化了`RealCall`,`RealCall`中初始化了`retryAndFollowUpInterceptor` : - client: OkHttpClient 實例 - originalRequest : 最初的Request - forWebSocket :是否支持websocket通信 - retryAndFollowUpInterceptor 從字面意思來說, 是重試和重定向攔截器 ,至於它有什麼作用我們繼續往下看 ### 同步請求分析 ``` Response response = call.execute(); ``` 我們點進`execute()`中查看: ``` @Override public Response execute() throws IOException { synchronized (this) { if (executed) throw new IllegalStateException("Already Executed"); executed = true; } captureCallStackTrace(); eventListener.callStart(this); try { client.dispatcher().executed(this); Response result = getResponseWithInterceptorChain(); if (result == null) throw new IOException("Canceled"); return result; } catch (IOException e) { eventListener.callFailed(this, e); throw e; } finally { client.dispatcher().finished(this); } } ``` 從上面代碼得知步驟: (1).通過 ` synchronized ` 保證線程同步,判斷是否已經執行過 ,如果是直接拋異常 (2). `captureCallStackTrace();` 字面意思:捕獲調用堆棧跟蹤,我們通過源碼發現裡面涉及到了`retryAndFollowUpInterceptor` (3). ` eventListener` 回調` CallStart()` (4). `client.dispatcher().executed(this);` 看到了`dispatcher`是不是很熟悉?之前在分析`okhttpClient`初始化的時候遇到了,我們點擊`executed()`方法進去: ``` synchronized void executed(RealCall call) { runningSyncCalls.add(call); } ``` 發現把我們傳進來的`realcall`放到了`runningSyncCalls`隊列中,從字面意思來說就是正在運行的同步的調用隊列中,為什麼說是隊列呢? : ``` private final Deque