本來這篇文章上個星期就寫好了,但是當時准備上傳的時候,公司停電了,而且沒保存,所以,沒辦法,又得重新寫了。說一下我個人的想法啊,很多人覺得看源碼特別難,無從下手,很多源碼看不懂。我覺得這是很正常的事,除非某個框架代碼是你寫的,
不然,你很難把每一句代碼都搞懂,就連框架的作者,時間一久,都沒有辦法保證說每一句代碼都能夠看得懂。我們花個三四天,一兩個星期,都很難把我們自己公司新接手的項目熟悉完,更何況是這些框架了。我說一下我平時是怎么看框架源碼的吧,每一個框架,首先,會用,這是最基本的,連用都不會用,還別談其他的了。其次,每一個框架,基本上都會有流程圖,這些流程圖,在網上都有。我們找到這個流程圖,這個流程圖,基本上都是整個框架的主干,我們順着這個主干閱讀,你就會發現,很明了,很清晰。當你把主體熟悉完以后,如果,你想更加深入的了解,你就可以在這個主體基礎上慢慢的延伸出去。好了,廢話不多說了,今天我們來了解一下OkHttp,這里是基於OkHttp3的源碼,OkHttp2.x的源碼和OkHttp3的會有點區別。我們按照上面的說的方式來閱讀一下。
OkHttp流程圖
OkHttp基本使用
gradle依賴
1 implementation 'com.squareup.okhttp3:okhttp:3.11.0' 2 implementation 'com.squareup.okio:okio:1.15.0'
1 /** 2 *這里拿get請求來 3 * 異步的get請求 4 */ 5 public void okhttpAsyn() { 6 //設置超時的時間 7 OkHttpClient.Builder builder = new OkHttpClient.Builder() 8 .connectTimeout(15, TimeUnit.SECONDS) 9 .writeTimeout(20, TimeUnit.SECONDS) 10 .readTimeout(20, TimeUnit.SECONDS) 11 ; 12 OkHttpClient okHttpClient = builder.build(); 13 Request request = new Request.Builder() 14 .get() //設置請求模式 15 .url("https://www.baidu.com/") 16 .build(); 17 18 Call call = okHttpClient.newCall(request); 19 call.enqueue(new Callback() { 20 @Override 21 public void onFailure(Call call, IOException e) { 22 Log.d("MainActivity", "-----------onFailure-----------"); 23 } 24 25 @Override 26 public void onResponse(Call call, Response response) throws IOException { 27 Log.d("MainActivity", "----onResponse----" + response.body().toString()); 28 runOnUiThread(new Runnable() { 29 @Override 30 public void run() { 31 Toast.makeText(MainActivity.this, "請求成功", Toast.LENGTH_LONG).show(); 32 } 33 }); 34 35 } 36 }); 37 }
OkHttp源碼分析
從OkHttp的基本使用中,我們看到,通過okHttpClient.newCall()方法,拿到這個call對象,我們看看newCall是怎么走的
1 /** 2 * Prepares the {@code request} to be executed at some point in the future. 3 */ 4 @Override public Call newCall(Request request) { 5 return RealCall.newRealCall(this, request, false /* for web socket */); 6 } 7 8 9 static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) { 10 // Safely publish the Call instance to the EventListener. 11 RealCall call = new RealCall(client, originalRequest, forWebSocket); 12 call.eventListener = client.eventListenerFactory().create(call); 13 return call; 14 }
從這里的源碼知道,okHttpClient.newCall()實際上返回的是RealCall對象,而call.enqueue(),實際上是調用的了RealCall中的enqueue()方法,我們看看enqueue()方法方法怎么走。
1 @Override public void enqueue(Callback responseCallback) { 2 synchronized (this) { 3 if (executed) throw new IllegalStateException("Already Executed"); 4 executed = true; 5 } 6 captureCallStackTrace(); 7 eventListener.callStart(this); 8 client.dispatcher().enqueue(new AsyncCall(responseCallback)); 9 }
可以看到client.dispatcher().enqueue(new AsyncCall(responseCallback));這句代碼,也就是說,最終是有的請求是有dispatcher來完成,我們看看dispatcher。
1 /* 2 * Copyright (C) 2013 Square, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package okhttp3; 17 18 import java.util.ArrayDeque; 19 import java.util.ArrayList; 20 import java.util.Collections; 21 import java.util.Deque; 22 import java.util.Iterator; 23 import java.util.List; 24 import java.util.concurrent.ExecutorService; 25 import java.util.concurrent.SynchronousQueue; 26 import java.util.concurrent.ThreadPoolExecutor; 27 import java.util.concurrent.TimeUnit; 28 import javax.annotation.Nullable; 29 import okhttp3.RealCall.AsyncCall; 30 import okhttp3.internal.Util; 31 32 /** 33 * Policy on when async requests are executed. 34 * 35 * <p>Each dispatcher uses an {@link ExecutorService} to run calls internally. If you supply your 36 * own executor, it should be able to run {@linkplain #getMaxRequests the configured maximum} number 37 * of calls concurrently. 38 */ 39 public final class Dispatcher { 40 //最大請求的並發數 41 private int maxRequests = 64; 42 //每個主機最大請求數 43 private int maxRequestsPerHost = 5; 44 private @Nullable Runnable idleCallback; 45 46 /** 消費線程池 */ 47 private @Nullable ExecutorService executorService; 48 49 /** 准備運行的異步請求隊列 */ 50 private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>(); 51 52 /** 正在運行的異步請求隊列 */ 53 private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>(); 54 55 /** 正在運行的同步請求隊列 */ 56 private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>(); 57 58 /** 構造方法 */ 59 public Dispatcher(ExecutorService executorService) { 60 this.executorService = executorService; 61 } 62 63 public Dispatcher() { 64 } 65 66 public synchronized ExecutorService executorService() { 67 if (executorService == null) { 68 executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, 69 new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false)); 70 } 71 return executorService; 72 } 73 74 75 76 77 /** 78 * 79 *設置並發執行最大的請求數量 80 * <p>If more than {@code maxRequests} requests are in flight when this is invoked, those requests 81 * will remain in flight. 82 */ 83 public synchronized void setMaxRequests(int maxRequests) { 84 if (maxRequests < 1) { 85 throw new IllegalArgumentException("max < 1: " + maxRequests); 86 } 87 this.maxRequests = maxRequests; 88 promoteCalls(); 89 } 90 91 //獲取到最大請求的數量 92 public synchronized int getMaxRequests() { 93 return maxRequests; 94 } 95 96 /** 97 * 設置每個主機並發執行的請求的最大數量 98 * <p>If more than {@code maxRequestsPerHost} requests are in flight when this is invoked, those 99 * requests will remain in flight. 100 * 101 * <p>WebSocket connections to hosts <b>do not</b> count against this limit. 102 */ 103 public synchronized void setMaxRequestsPerHost(int maxRequestsPerHost) { 104 if (maxRequestsPerHost < 1) { 105 throw new IllegalArgumentException("max < 1: " + maxRequestsPerHost); 106 } 107 this.maxRequestsPerHost = maxRequestsPerHost; 108 promoteCalls(); 109 } 110 111 //獲取每個主機最大並發數量 112 public synchronized int getMaxRequestsPerHost() { 113 return maxRequestsPerHost; 114 } 115 116 /** 117 * Set a callback to be invoked each time the dispatcher becomes idle (when the number of running 118 * calls returns to zero). 119 * 120 * <p>Note: The time at which a {@linkplain Call call} is considered idle is different depending 121 * on whether it was run {@linkplain Call#enqueue(Callback) asynchronously} or 122 * {@linkplain Call#execute() synchronously}. Asynchronous calls become idle after the 123 * {@link Callback#onResponse onResponse} or {@link Callback#onFailure onFailure} callback has 124 * returned. Synchronous calls become idle once {@link Call#execute() execute()} returns. This 125 * means that if you are doing synchronous calls the network layer will not truly be idle until 126 * every returned {@link Response} has been closed. 127 */ 128 public synchronized void setIdleCallback(@Nullable Runnable idleCallback) { 129 this.idleCallback = idleCallback; 130 } 131 132 synchronized void enqueue(AsyncCall call) { 133 if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) { 134 runningAsyncCalls.add(call); 135 executorService().execute(call); 136 } else { 137 readyAsyncCalls.add(call); 138 } 139 } 140 141 /** 142 * Cancel all calls currently enqueued or executing. Includes calls executed both {@linkplain 143 * Call#execute() synchronously} and {@linkplain Call#enqueue asynchronously}. 144 */ 145 public synchronized void cancelAll() { 146 for (AsyncCall call : readyAsyncCalls) { 147 call.get().cancel(); 148 } 149 150 for (AsyncCall call : runningAsyncCalls) { 151 call.get().cancel(); 152 } 153 154 for (RealCall call : runningSyncCalls) { 155 call.cancel(); 156 } 157 } 158 159 private void promoteCalls() { 160 if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity. 161 if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote. 162 163 for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) { 164 AsyncCall call = i.next(); 165 166 if (runningCallsForHost(call) < maxRequestsPerHost) { 167 i.remove(); 168 runningAsyncCalls.add(call); 169 executorService().execute(call); 170 } 171 172 if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity. 173 } 174 } 175 176 //----------------省略若干代碼----------------------- 177 178 }
我們來找到這段代碼
1 synchronized void enqueue(AsyncCall call) { 2 if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) { 3 runningAsyncCalls.add(call); 4 executorService().execute(call); 5 } else { 6 readyAsyncCalls.add(call); 7 } 8 }
當正在運行的異步請求隊列中的數量小於64並且正在運行的請求主機數小於5時則把請求加載到runningAsyncCalls中並在線程池中執行,否則就再入到readyAsyncCalls中進行緩存等待。而runningAsyncCalls這個請求隊列存放的就是AsyncCall對象,而這個AsyncCall就是RealCall的內部類,也就是說executorService().execute(call);實際上走的是RealCall類中的execute()方法.
1 @Override protected void execute() { 2 boolean signalledCallback = false; 3 try { 4 Response response = getResponseWithInterceptorChain(); 5 if (retryAndFollowUpInterceptor.isCanceled()) { 6 signalledCallback = true; 7 responseCallback.onFailure(RealCall.this, new IOException("Canceled")); 8 } else { 9 signalledCallback = true; 10 responseCallback.onResponse(RealCall.this, response); 11 } 12 } catch (IOException e) { 13 if (signalledCallback) { 14 // Do not signal the callback twice! 15 Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e); 16 } else { 17 eventListener.callFailed(RealCall.this, e); 18 responseCallback.onFailure(RealCall.this, e); 19 } 20 } finally { 21 client.dispatcher().finished(this); 22 } 23 }
這部分的代碼,相信很多人都能夠看的明白,無非就是一些成功,失敗的回調,這段代碼,最重要的是esponse response = getResponseWithInterceptorChain();和client.dispatcher().finished(this);我們先來看看client.dispatcher().finished(this);這句代碼是怎么執行的。
1 /** Used by {@code AsyncCall#run} to signal completion. */ 2 void finished(AsyncCall call) { 3 finished(runningAsyncCalls, call, true); 4 } 5 6 /** Used by {@code Call#execute} to signal completion. */ 7 void finished(RealCall call) { 8 finished(runningSyncCalls, call, false); 9 } 10 11 private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) { 12 int runningCallsCount; 13 Runnable idleCallback; 14 synchronized (this) { 15 if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!"); 16 if (promoteCalls) promoteCalls(); 17 runningCallsCount = runningCallsCount(); 18 idleCallback = this.idleCallback; 19 } 20 21 if (runningCallsCount == 0 && idleCallback != null) { 22 idleCallback.run(); 23 } 24 } 25 26 private void promoteCalls() { 27 if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity. 28 if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote. 29 30 for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) { 31 AsyncCall call = i.next(); 32 33 if (runningCallsForHost(call) < maxRequestsPerHost) { 34 i.remove(); 35 runningAsyncCalls.add(call); 36 executorService().execute(call); 37 } 38 39 if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity. 40 } 41 }
由於client.dispatcher().finished(this);這句代碼是放到finally中執行的,所以無論什么情況,都會執行上面的promoteCalls()方法,而從promoteCalls()方法中可以看出通過遍歷來獲取到下一個請求從而執行下一個網絡請求。
回過頭來,我們看看這一句代碼Response response = getResponseWithInterceptorChain(); 通過getResponseWithInterceptorChain();來獲取到response,然后回調返回。很明顯getResponseWithInterceptorChain()這句代碼里面進行了網絡請求。我們看看是怎么執行的。
1 Response getResponseWithInterceptorChain() throws IOException { 2 // Build a full stack of interceptors. 3 List<Interceptor> interceptors = new ArrayList<>(); 4 interceptors.addAll(client.interceptors()); 5 interceptors.add(retryAndFollowUpInterceptor); 6 interceptors.add(new BridgeInterceptor(client.cookieJar())); 7 interceptors.add(new CacheInterceptor(client.internalCache())); 8 interceptors.add(new ConnectInterceptor(client)); 9 if (!forWebSocket) { 10 interceptors.addAll(client.networkInterceptors()); 11 } 12 interceptors.add(new CallServerInterceptor(forWebSocket)); 13 14 Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, 15 originalRequest, this, eventListener, client.connectTimeoutMillis(), 16 client.readTimeoutMillis(), client.writeTimeoutMillis()); 17 18 return chain.proceed(originalRequest); 19 } 20 }
從上面代碼可以知道,緩存,網絡請求,都封裝成攔截器的形式。攔截器主要用來觀察,修改以及可能短路的請求輸出和響應的回來。最后return chain.proceed,而chain是通過new RealInterceptorChain來獲取到的,我們來看看RealInterceptorChain對象,然后找到proceed()方法。
1 public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec, 2 RealConnection connection) throws IOException { 3 if (index >= interceptors.size()) throw new AssertionError(); 4 5 calls++; 6 7 // If we already have a stream, confirm that the incoming request will use it. 8 if (this.httpCodec != null && !this.connection.supportsUrl(request.url())) { 9 throw new IllegalStateException("network interceptor " + interceptors.get(index - 1) 10 + " must retain the same host and port"); 11 } 12 13 // If we already have a stream, confirm that this is the only call to chain.proceed(). 14 if (this.httpCodec != null && calls > 1) { 15 throw new IllegalStateException("network interceptor " + interceptors.get(index - 1) 16 + " must call proceed() exactly once"); 17 } 18 19 // 調用下一個攔截器 20 RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec, 21 connection, index + 1, request, call, eventListener, connectTimeout, readTimeout, 22 writeTimeout); 23 Interceptor interceptor = interceptors.get(index); 24 Response response = interceptor.intercept(next); //調用攔截器中的intercept()方法 25 26 // Confirm that the next interceptor made its required call to chain.proceed(). 27 if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) { 28 throw new IllegalStateException("network interceptor " + interceptor 29 + " must call proceed() exactly once"); 30 } 31 32 // Confirm that the intercepted response isn't null. 33 if (response == null) { 34 throw new NullPointerException("interceptor " + interceptor + " returned null"); 35 } 36 37 if (response.body() == null) { 38 throw new IllegalStateException( 39 "interceptor " + interceptor + " returned a response with no body"); 40 } 41 42 return response; 43 }
從上面的代碼可以看出來,chain.proceed主要是講集合中的攔截器遍歷出來,然后通過調用每一個攔截器中的intercept()方法,然后獲取到response結果,返回。
我們看看CacheInterceptor這個類,找到intercept()方法。
1 @Override public Response intercept(Chain chain) throws IOException { 2 Response cacheCandidate = cache != null 3 ? cache.get(chain.request()) 4 : null; 5 6 long now = System.currentTimeMillis(); 7 8 //創建CacheStrategy.Factory對象,進行緩存配置 9 CacheStrategy strategy = new CacheStrategy.Factory(now, chain.request(), cacheCandidate).get(); 10 //網絡請求 11 Request networkRequest = strategy.networkRequest; 12 //緩存響應 13 Response cacheResponse = strategy.cacheResponse; 14 15 if (cache != null) { 16 //記錄當前請求是網絡發起還是緩存發起 17 cache.trackResponse(strategy); 18 } 19 20 if (cacheCandidate != null && cacheResponse == null) { 21 closeQuietly(cacheCandidate.body()); // The cache candidate wasn't applicable. Close it. 22 } 23 24 // 不進行網絡請求並且緩存不存在或者過期則返回504錯誤 25 if (networkRequest == null && cacheResponse == null) { 26 return new Response.Builder() 27 .request(chain.request()) 28 .protocol(Protocol.HTTP_1_1) 29 .code(504) 30 .message("Unsatisfiable Request (only-if-cached)") 31 .body(Util.EMPTY_RESPONSE) 32 .sentRequestAtMillis(-1L) 33 .receivedResponseAtMillis(System.currentTimeMillis()) 34 .build(); 35 } 36 37 // 不進行網絡請求,而且緩存可以使用,直接返回緩存 38 if (networkRequest == null) { 39 return cacheResponse.newBuilder() 40 .cacheResponse(stripBody(cacheResponse)) 41 .build(); 42 } 43 44 //進行網絡請求 45 Response networkResponse = null; 46 try { 47 networkResponse = chain.proceed(networkRequest); 48 } finally { 49 // If we're crashing on I/O or otherwise, don't leak the cache body. 50 if (networkResponse == null && cacheCandidate != null) { 51 closeQuietly(cacheCandidate.body()); 52 } 53 } 54 55 //---------省略若干代碼------------- 56 57 return response; 58 }
上面我做了很多注釋,基本的流程是有緩存就取緩存里面的,沒有緩存就請求網絡。我們來看看網絡請求的類CallServerInterceptor
1 /* 2 * Copyright (C) 2016 Square, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package okhttp3.internal.http; 17 18 import java.io.IOException; 19 import java.net.ProtocolException; 20 import okhttp3.Interceptor; 21 import okhttp3.Request; 22 import okhttp3.Response; 23 import okhttp3.internal.Util; 24 import okhttp3.internal.connection.RealConnection; 25 import okhttp3.internal.connection.StreamAllocation; 26 import okio.Buffer; 27 import okio.BufferedSink; 28 import okio.ForwardingSink; 29 import okio.Okio; 30 import okio.Sink; 31 32 /** This is the last interceptor in the chain. It makes a network call to the server. */ 33 public final class CallServerInterceptor implements Interceptor { 34 private final boolean forWebSocket; 35 36 public CallServerInterceptor(boolean forWebSocket) { 37 this.forWebSocket = forWebSocket; 38 } 39 40 @Override public Response intercept(Chain chain) throws IOException { 41 RealInterceptorChain realChain = (RealInterceptorChain) chain; 42 HttpCodec httpCodec = realChain.httpStream(); 43 StreamAllocation streamAllocation = realChain.streamAllocation(); 44 RealConnection connection = (RealConnection) realChain.connection(); 45 Request request = realChain.request(); 46 47 long sentRequestMillis = System.currentTimeMillis(); 48 49 realChain.eventListener().requestHeadersStart(realChain.call()); 50 httpCodec.writeRequestHeaders(request); 51 realChain.eventListener().requestHeadersEnd(realChain.call(), request); 52 53 Response.Builder responseBuilder = null; 54 if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) { 55 // If there's a "Expect: 100-continue" header on the request, wait for a "HTTP/1.1 100 56 // Continue" response before transmitting the request body. If we don't get that, return 57 // what we did get (such as a 4xx response) without ever transmitting the request body. 58 if ("100-continue".equalsIgnoreCase(request.header("Expect"))) { 59 httpCodec.flushRequest(); 60 realChain.eventListener().responseHeadersStart(realChain.call()); 61 responseBuilder = httpCodec.readResponseHeaders(true); 62 } 63 64 if (responseBuilder == null) { 65 // Write the request body if the "Expect: 100-continue" expectation was met. 66 realChain.eventListener().requestBodyStart(realChain.call()); 67 long contentLength = request.body().contentLength(); 68 CountingSink requestBodyOut = 69 new CountingSink(httpCodec.createRequestBody(request, contentLength)); 70 BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut); 71 72 request.body().writeTo(bufferedRequestBody); 73 bufferedRequestBody.close(); 74 realChain.eventListener() 75 .requestBodyEnd(realChain.call(), requestBodyOut.successfulCount); 76 } else if (!connection.isMultiplexed()) { 77 // If the "Expect: 100-continue" expectation wasn't met, prevent the HTTP/1 connection 78 // from being reused. Otherwise we're still obligated to transmit the request body to 79 // leave the connection in a consistent state. 80 streamAllocation.noNewStreams(); 81 } 82 } 83 84 httpCodec.finishRequest(); 85 86 if (responseBuilder == null) { 87 realChain.eventListener().responseHeadersStart(realChain.call()); 88 responseBuilder = httpCodec.readResponseHeaders(false); 89 } 90 91 Response response = responseBuilder 92 .request(request) 93 .handshake(streamAllocation.connection().handshake()) 94 .sentRequestAtMillis(sentRequestMillis) 95 .receivedResponseAtMillis(System.currentTimeMillis()) 96 .build(); 97 98 int code = response.code(); 99 if (code == 100) { 100 // server sent a 100-continue even though we did not request one. 101 // try again to read the actual response 102 responseBuilder = httpCodec.readResponseHeaders(false); 103 104 response = responseBuilder 105 .request(request) 106 .handshake(streamAllocation.connection().handshake()) 107 .sentRequestAtMillis(sentRequestMillis) 108 .receivedResponseAtMillis(System.currentTimeMillis()) 109 .build(); 110 111 code = response.code(); 112 } 113 114 realChain.eventListener() 115 .responseHeadersEnd(realChain.call(), response); 116 117 if (forWebSocket && code == 101) { 118 // Connection is upgrading, but we need to ensure interceptors see a non-null response body. 119 response = response.newBuilder() 120 .body(Util.EMPTY_RESPONSE) 121 .build(); 122 } else { 123 response = response.newBuilder() 124 .body(httpCodec.openResponseBody(response)) 125 .build(); 126 } 127 128 if ("close".equalsIgnoreCase(response.request().header("Connection")) 129 || "close".equalsIgnoreCase(response.header("Connection"))) { 130 streamAllocation.noNewStreams(); 131 } 132 133 if ((code == 204 || code == 205) && response.body().contentLength() > 0) { 134 throw new ProtocolException( 135 "HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength()); 136 } 137 138 return response; 139 } 140 }
到這里,基本上okhttp的整個流程就出來了,當然,這里只是一個整體的大概流程,如果要摳的很細,那就不是一篇文章能夠說明的了了........現在回過頭來再看一眼流程圖,是不是感覺特別明朗了。