OkHttpClient okHttpClient=new OkHttpClient(); Request request=new Request.Builder() .get() .url("www.baidu.com") .build(); Call call =okHttpClient.newCall(request).execute();
OkHttpClient okHttpClient=new OkHttpClient(); Request request=new Request.Builder() .get() .url("www.baidu.com") .build(); Call call=okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.i(TAG, "onFailure: "); } @Override public void onResponse(Call call, Response response) throws IOException { Log.i(TAG, "onResponse: "); } });
能夠看出不論是同步仍是異步請求,使用okhttp大體分爲3個步驟:
1. 建立okhttpclient
2. 建立請求的request
3. 經過client拿到call、發送請求web
注:okhttpclient和request的建立都可採用構造者模式,在構造過程當中可根據本身的實際需求設置相應的參數,如可在okhttpclient構造時添加自定義攔截器,在request構造過程當中設置鏈接超時時間等。設計模式
首先看下OkhttpClient這個類,使用步驟的第一步就是構造OkhttpClient對象。緩存
先貼下官方對OkhttpClient的定義安全
*Factory for {@linkplain Call calls}, which can be used to send HTTP requests and read their * responses. * OkHttpClients should be shared * OkHttp performs best when you create a single {@code OkHttpClient} instance and reuse it for * all of your HTTP calls. This is because each client holds its own connection pool and thread * pools. Reusing connections and threads reduces latency and saves memory. Conversely, creating a * client for each request wastes resources on idle pools.
OkhttpClient是用於發送請求和讀取響應的,官方建議建立一個單例的OkHttpClient,而且全部的http請求都複用它。由於每一個OkHttpClient都有本身的connection pool and thread pool。複用connection pool and thread pool能夠節約內存,相反若是爲每一個請求都建立一個OkHttpClient那麼會浪費idle pools中的資源。cookie
建立OkHttpClient有兩種方式:
一、經過構造函數
二、經過Builder()建立一個client並自定義設置網絡
同時還提供了一個newBuilder()來自定義client,它跟共享的client擁有相同的connection pool, thread pools, and configuration。咱們能夠用該方法來獲取特定設置的client。併發
OkHttpClient提供無參構造函數,由代碼可知它在內部調用OkHttpClient的有參構造函數
,在有參構造函數裏對OkHttpClient主要屬性作了初始化賦值。app
public OkHttpClient() { this(new Builder()); } OkHttpClient(Builder builder) { this.dispatcher = builder.dispatcher; this.proxy = builder.proxy; this.protocols = builder.protocols; this.connectionSpecs = builder.connectionSpecs; this.interceptors = Util.immutableList(builder.interceptors); this.networkInterceptors = Util.immutableList(builder.networkInterceptors); this.eventListenerFactory = builder.eventListenerFactory; this.proxySelector = builder.proxySelector; this.cookieJar = builder.cookieJar; this.cache = builder.cache; this.internalCache = builder.internalCache; this.socketFactory = builder.socketFactory; ...//省略N行 }
下面貼下OkHttpClient主要的屬性異步
public class OkHttpClient{ final Dispatcher dispatcher;//分發器 final @Nullable Proxy proxy;//代理 final List<Protocol> protocols;//協議 final List<ConnectionSpec> connectionSpecs;//傳輸層版本和鏈接協議 final List<Interceptor> interceptors;//攔截器 (okhttp核心機制) final List<Interceptor> networkInterceptors;//網絡攔截器 final EventListener.Factory eventListenerFactory; final ProxySelector proxySelector;//代理選擇器 final CookieJar cookieJar;//cookie final @Nullable Cache cache;//cache 緩存 final @Nullable InternalCache internalCache;//內部緩存 final SocketFactory socketFactory;//socket 工廠 final @Nullable SSLSocketFactory sslSocketFactory;//安全套層socket工廠 用於https final @Nullable CertificateChainCleaner certificateChainCleaner;//驗證確認響應書,適用HTTPS 請求鏈接的主機名 final HostnameVerifier hostnameVerifier;//主機名字確認 final CertificatePinner certificatePinner;//證書鏈 final Authenticator proxyAuthenticator;//代理身份驗證 final Authenticator authenticator;//本地省份驗證 final ConnectionPool connectionPool;//連接池 複用鏈接 final Dns dns; //域名 final boolean followSslRedirects;//安全套接層重定向 final boolean followRedirects;//本地重定向 final boolean retryOnConnectionFailure;//鏈接失敗是否重試 final int connectTimeout;//鏈接超時時間 final int readTimeout;//讀取超時時間 final int writeTimeout;//寫入超時時間 }
經過瀏覽源碼咱們能夠發現OkHttpClient採用了構造者設計模式,這樣簡化參數設置,下降使用成本。好比咱們前面簡單使用的例子socket
OkHttpClient類還有一個須要瞭解的函數就是newCall,由於OkHttpClient實現Call.Factory接口因此覆寫了newCall方法,在方法內部返回的是一個RealCall實例。
/** * Prepares the {@code request} to be executed at some point in the future. */ @Override public Call newCall(Request request) { return RealCall.newRealCall(this, request, false /* for web socket */); }
OkHttpClient構造好了以後接下來就是建立request,request就是咱們要發送的請求。它也是經過builder模式構造的。下面貼下Request的主要屬性以及其構造函數。
public final class Request { final HttpUrl url;//請求url地址 final String method;//請求方式 final Headers headers;//請求頭 final @Nullable RequestBody body;//請求body final Map<Class<?>, Object> tags;//請求tags用來標記一類請求如 設置以後能夠經過tags取消擁有該tag的請求 Request(Builder builder) { this.url = builder.url; this.method = builder.method; this.headers = builder.headers.build(); this.body = builder.body; this.tags = Util.immutableMap(builder.tags); } ... }
經過Request咱們能夠獲得咱們想要的請求,而後下一步就是獲取call實例而後發送請求。
在介紹OkHttpClient類的時候咱們已經說過call對象是經過OkHttpClient的newCall方法得到的實際返回的是RealCall對象,也就是說真正發送的請求是RealCall,那麼咱們來看下RealCall這個類
final class RealCall implements Call { final OkHttpClient client; //realcall持有client private Transmitter transmitter;//暫時不知道其做用 /** The application's original request unadulterated by redirects or auth headers. */ final Request originalRequest;//原始請求 final boolean forWebSocket;// // Guarded by this. private boolean executed;//請求是否執行標誌位 private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) { //構造函數 this.client = client; this.originalRequest = originalRequest; this.forWebSocket = forWebSocket; } static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {//okhttpclient即經過該函數返回call // Safely publish the Call instance to the EventListener. RealCall call = new RealCall(client, originalRequest, forWebSocket); call.transmitter = new Transmitter(client, call); return call; }
RealCall實現的Call接口,其newCall函數內部經過RealCall的構造函數實例化一個call而後返回該call。
最後就是發送請求了,有兩種方式:同步和異步。咱們先看下同步請求的方式,同步請求是經過execute發送的
@Override public Response execute() throws IOException { synchronized (this) {//1 if (executed) throw new IllegalStateException("Already Executed"); executed = true; } transmitter.timeoutEnter(); transmitter.callStart(); try { client.dispatcher().executed(this);//2 return getResponseWithInterceptorChain();//3 } finally { client.dispatcher().finished(this);//4 } }
execute首先(註釋1處)會synchronized來檢查executed值從而確保每一個請求只能執行一次。隨後調用dispatcher的executed(註釋2處)。
來看下Dispatcher這個類
public final class Dispatcher { private int maxRequests = 64;//最大請求數 private int maxRequestsPerHost = 5;//每一個host的最大請求數 private @Nullable Runnable idleCallback;//請求隊列空閒回調 /** Executes calls. Created lazily. */ private @Nullable ExecutorService executorService; //執行請求的線程池 /** 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<>();//同步請求隊列
能夠看出okhttp雖然支持併發請求可是有最大併發請求數的限制。並且okhttp針對不一樣的請求方式提供了不一樣的請求隊列。dispatcher這個類主要的做用就是根據request的請求方式以及根據當前client的執行狀況把新建立的call請求分發至不一樣的隊列中去執行。
瞭解了dispatcher類做用咱們看下它的exectued函數
synchronized void executed(RealCall call) { runningSyncCalls.add(call); }
很簡單它只是把傳入的call對象添加到同步請求隊列中(runningSyncCalls)。那請求具體是如何發送的呢 咱們接着看RealCall的exectued函數。
在註釋3處經過調用getResponseWithInterceptorChain()獲取respone並返回該respone。
Response getResponseWithInterceptorChain() throws IOException { // Build a full stack of interceptors. List<Interceptor> interceptors = new ArrayList<>(); interceptors.addAll(client.interceptors());//若是在client中設置了自定義interceptor那麼會放到interceptors中 interceptors.add(new RetryAndFollowUpInterceptor(client));//添加劇試與重定向攔截器 interceptors.add(new BridgeInterceptor(client.cookieJar()));//添加橋接攔截器 interceptors.add(new CacheInterceptor(client.internalCache()));//添加緩存攔截器 interceptors.add(new ConnectInterceptor(client)); if (!forWebSocket) { interceptors.addAll(client.networkInterceptors()); } interceptors.add(new CallServerInterceptor(forWebSocket));//添加CallServer攔截器 Interceptor.Chain chain = new RealInterceptorChain(interceptors, transmitter, null, 0, originalRequest, this, client.connectTimeoutMillis(), client.readTimeoutMillis(), client.writeTimeoutMillis());// 建立RealInterceptorChain實例,把interceptors傳入 boolean calledNoMoreExchanges = false; try { Response response = chain.proceed(originalRequest);//經過proceed鏈式獲取respone if (transmitter.isCanceled()) { closeQuietly(response); throw new IOException("Canceled"); } return response;//返回respone } catch (IOException e) { calledNoMoreExchanges = true; throw transmitter.noMoreExchanges(e); } finally { if (!calledNoMoreExchanges) { transmitter.noMoreExchanges(null); } } }
getResponseWithInterceptorChain首先會把自定義以及okhttp定義的攔截器加到interceptors的list中,而後構造RealInterceptorChain攔截器鏈,調用chain.proceed鏈式調用各個攔截器並最終得到respone。
Interceptor能夠說是okhttp的核心機制之一,咱們一塊兒來看下
public interface Interceptor { Response intercept(Chain chain) throws IOException; interface Chain { Request request(); Response proceed(Request request) throws IOException; /** * Returns the connection the request will be executed on. This is only available in the chains * of network interceptors; for application interceptors this is always null. */ @Nullable Connection connection(); Call call(); int connectTimeoutMillis(); Chain withConnectTimeout(int timeout, TimeUnit unit); int readTimeoutMillis(); Chain withReadTimeout(int timeout, TimeUnit unit); int writeTimeoutMillis(); Chain withWriteTimeout(int timeout, TimeUnit unit); } }
它是okhttp定義的一個接口類,而且okhttp提供了5個實現類,他們就是getResponseWithInterceptorChain()中添加到interceptors中的5個Interceptor,他們做用各不相同,這個之後會單獨分析。除此以外咱們還能夠自定義本身的攔截器。
瞭解了攔截器的概念以後咱們看下RealInterceptorChain及其proceed函數
public final class RealInterceptorChain implements Interceptor.Chain { private final List<Interceptor> interceptors;//攔截器list private final Transmitter transmitter; private final @Nullable Exchange exchange; private final int index; private final Request request;//請求 private final Call call; private final int connectTimeout; private final int readTimeout; private final int writeTimeout; private int calls; public RealInterceptorChain(List<Interceptor> interceptors, Transmitter transmitter, @Nullable Exchange exchange, int index, Request request, Call call, int connectTimeout, int readTimeout, int writeTimeout) {//構造函數 this.interceptors = interceptors; this.transmitter = transmitter; this.exchange = exchange; this.index = index; this.request = request; this.call = call; this.connectTimeout = connectTimeout; this.readTimeout = readTimeout; this.writeTimeout = writeTimeout; } @Override public Response proceed(Request request) throws IOException {//proceed方法實際調用同名的proceed方法 return proceed(request, transmitter, exchange); } public Response proceed(Request request, Transmitter transmitter, @Nullable Exchange exchange) throws IOException {//1 if (index >= interceptors.size()) throw new AssertionError(); calls++; // If we already have a stream, confirm that the incoming request will use it. if (this.exchange != null && !this.exchange.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.exchange != null && calls > 1) { throw new IllegalStateException("network interceptor " + interceptors.get(index - 1) + " must call proceed() exactly once"); } // 2 //Call the next interceptor in the chain. RealInterceptorChain next = new RealInterceptorChain(interceptors, transmitter, exchange, index + 1, request, call, connectTimeout, readTimeout, writeTimeout); Interceptor interceptor = interceptors.get(index); Response response = interceptor.intercept(next); // Confirm that the next interceptor made its required call to chain.proceed(). if (exchange != 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"); } if (response.body() == null) { throw new IllegalStateException( "interceptor " + interceptor + " returned a response with no body"); } return response; }
RealInterceptorChain做爲攔截器鏈它持有整個應用的攔截器以及網絡攔截器。該類的proceed方法實際是調用了該類重載的proceed方法(註釋1處)。在註釋2處,調用攔截器鏈中的下一個攔截器。在這裏new了一個RealInterceptorChain,注意這裏傳入的index加了1(getResponseWithInterceptorChain傳入的index爲0),這表明攔截器鏈中的下一個攔截器的index,以後根據index獲取當前的攔截器並調用其intercept方法。intercept是接口Interceptor的一個方法,由具體的實現類實現,此處咱們以RetryAndFollowUpInterceptor爲例看下intercept方法中作了什麼事情。
public final class RetryAndFollowUpInterceptor implements Interceptor { private final OkHttpClient client;//持有的client @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request();//獲取傳入的chain的request 此處的request是next的request RealInterceptorChain realChain = (RealInterceptorChain) chain; Transmitter transmitter = realChain.transmitter(); int followUpCount = 0; Response priorResponse = null; while (true) { transmitter.prepareToConnect(request); if (transmitter.isCanceled()) { throw new IOException("Canceled"); } Response response; boolean success = false; try { response = realChain.proceed(request, transmitter, null);//調用next的proceed方法 success = true; } catch (RouteException e) { // The attempt to connect via a route failed. The request will not have been sent. if (!recover(e.getLastConnectException(), transmitter, false, request)) { throw e.getFirstConnectException(); } continue; } catch (IOException e) { // An attempt to communicate with a server failed. The request may have been sent. boolean requestSendStarted = !(e instanceof ConnectionShutdownException); if (!recover(e, transmitter, requestSendStarted, request)) throw e; continue; } finally { // The network call threw an exception. Release any resources. if (!success) { transmitter.exchangeDoneDueToException(); } } // Attach the prior response if it exists. Such responses never have a body. if (priorResponse != null) { response = response.newBuilder() .priorResponse(priorResponse.newBuilder() .body(null) .build()) .build(); } Exchange exchange = Internal.instance.exchange(response); Route route = exchange != null ? exchange.connection().route() : null; Request followUp = followUpRequest(response, route);//處理請求重定向 if (followUp == null) { if (exchange != null && exchange.isDuplex()) { transmitter.timeoutEarlyExit(); } return response;//直到沒有重定向以後返回respone } RequestBody followUpBody = followUp.body(); if (followUpBody != null && followUpBody.isOneShot()) { return response; } closeQuietly(response.body()); if (transmitter.hasExchange()) { exchange.detachWithViolence(); } if (++followUpCount > MAX_FOLLOW_UPS) { throw new ProtocolException("Too many follow-up requests: " + followUpCount); } request = followUp; priorResponse = response; } } }
咱們看到在RetryAndFollowUpInterceptor的intercept方法中會調用傳入的next(即攔截器鏈中當前攔截器的下一個攔截器)的proceed方法,這樣就能夠鏈式的依次調用chain中全部攔截器,每一個攔截器都執行本身的任務最終返回respone。該respone經過RealCall的getResponseWithInterceptorChain返回到execute方法並最終變成咱們得到的respone。至此同步請求得到了respone,最後的操做就是在RealCall的execute方法中調用finished方法
@Override public Response execute() throws IOException { synchronized (this) { if (executed) throw new IllegalStateException("Already Executed"); executed = true; } transmitter.timeoutEnter(); transmitter.callStart(); try { client.dispatcher().executed(this); return getResponseWithInterceptorChain(); } finally { client.dispatcher().finished(this);//拿到respone後調用finish方法 } }
該方法是dispatcher提供的
void finished(RealCall call) { finished(runningSyncCalls, call); } private <T> void finished(Deque<T> calls, T call) { Runnable idleCallback; synchronized (this) { if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");//從同步執行隊列移除該call 移除失敗會拋出異常 idleCallback = this.idleCallback; } boolean isRunning = promoteAndExecute();//1 if (!isRunning && idleCallback != null) { idleCallback.run();//若是isRuning爲false而且idleCallback不爲空就執行idleCallback。 } }
咱們看下promoteAndExecute()這個方法
private boolean promoteAndExecute() { assert (!Thread.holdsLock(this)); List<AsyncCall> executableCalls = new ArrayList<>(); boolean isRunning; synchronized (this) { for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {//1 AsyncCall asyncCall = i.next(); if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity. if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity. i.remove(); asyncCall.callsPerHost().incrementAndGet(); executableCalls.add(asyncCall); runningAsyncCalls.add(asyncCall); } isRunning = runningCallsCount() > 0; } for (int i = 0, size = executableCalls.size(); i < size; i++) {//2 AsyncCall asyncCall = executableCalls.get(i); asyncCall.executeOn(executorService()); } return isRunning; }
該方法主要是兩個for循環,首先第一個for循環(註釋1處)遍歷準備就緒隊列若是不爲空且知足必定條件則添加到executableCalls中,可是在同步請求時準備就緒隊列(readyAsyncCalls)爲空,executableCalls也爲空,因此兩個for循環都不會進入(實際上該方法是爲異步請求準備的)函數最終返回false。
此時回到dispatcher的finish()方法,它會判斷promoteAndExecute()返回值和idleCallback是否爲空,若是isRuning爲false而且idleCallback不爲空就執行idleCallback,不然就什麼都不作。
至此同步請求流程分析完畢。
異步請求跟同步請求不一樣的地方就是它是調用RealCall的enqueue方法
@Override public void enqueue(Callback responseCallback) { synchronized (this) { if (executed) throw new IllegalStateException("Already Executed"); executed = true; } transmitter.callStart(); client.dispatcher().enqueue(new AsyncCall(responseCallback));//執行dispatcher的enqueue }
在方法內部調用dispatcher的enqueue並傳入AsyncCall參數,咱們先來看下AsyncCall再分析異步請求流程
final class AsyncCall extends NamedRunnable { private final Callback responseCallback; private volatile AtomicInteger callsPerHost = new AtomicInteger(0); AsyncCall(Callback responseCallback) { super("OkHttp %s", redactedUrl()); this.responseCallback = responseCallback; } }
AsyncCall是RealCall的一個內部類它繼承自NamedRunnable
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(); }
NamedRunnable其實就是一個實現Runnable的線程類。在它的run方法中調用了其提供的抽象函數execute(),execute()的實現是在AsyncCall
@Override protected void execute() { boolean signalledCallback = false; transmitter.timeoutEnter(); try { Response response = getResponseWithInterceptorChain(); 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); } }
能夠看到這跟同步請求的過程是同樣的先經過getResponseWithInterceptorChain()鏈式調用攔截鏈去得到resopne,以後是經過callback回調結果,最後調用finished。
分析AsyncCall以後咱們能夠大體猜想出異步請求的實現是經過線程去執行Call,請求的執行過程跟同步請求是同樣的只不過最後是經過callbcak返回。
好了,咱們來看下具體的異步請求流程,以前說到dispatcher的enqueue方法,那咱們來看下這個方法都作了什麼
void enqueue(AsyncCall call) { synchronized (this) { readyAsyncCalls.add(call);//添加到異步準備就緒隊列 // Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to // the same host. if (!call.get().forWebSocket) { AsyncCall existingCall = findExistingCallWithHost(call.host()); if (existingCall != null) call.reuseCallsPerHostFrom(existingCall); } } promoteAndExecute();//執行請求 }
很簡單在方法內部先是把call添加到異步準備就緒隊列而後調用了 promoteAndExecute,promoteAndExecute咱們以前在同步請求分析過它內部主要是兩個for循環,在同步請求時這兩個for循環都是不知足條件的,那咱們看下異步請求時
private boolean promoteAndExecute() { assert (!Thread.holdsLock(this)); List<AsyncCall> executableCalls = new ArrayList<>(); boolean isRunning; synchronized (this) { for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {//把異步準備就緒對列中的call取出 AsyncCall asyncCall = i.next(); //判斷最大請求數以及每一個host請求數是否符合要求 if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity. if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity. //移除準備就緒隊列中的call i.remove(); asyncCall.callsPerHost().incrementAndGet();//記錄該call的host的請求數 executableCalls.add(asyncCall);//添加到executableCalls runningAsyncCalls.add(asyncCall);//添加到異步執行隊列 } isRunning = runningCallsCount() > 0; } for (int i = 0, size = executableCalls.size(); i < size; i++) {//executableCalls不爲空,取出執行 AsyncCall asyncCall = executableCalls.get(i); asyncCall.executeOn(executorService());//call實際執行 } return isRunning; }
由於在以前已經把call添加到了異步準備就緒隊列(readyAsyncCalls
),因此第一個for是能夠進入的,在第一個for循環內部首先會先判斷當前準備就緒隊列中的call是否達到了最大請求數即最大併發請求數,而後判斷單個host是否達到最大請求數。以後就是把當前的call添加到executableCalls和runningAsyncCalls兩個隊列中。以後進入第二個for循環,在這個for循環中依次其中取出call對象並調用其executeO函數。
注意在execute函數中傳入的executorService實際上是一個線程池
public synchronized ExecutorService executorService() { if (executorService == null) { executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<>(), Util.threadFactory("OkHttp Dispatcher", false)); } return executorService; }
能夠看出executorService是一個僅有非核心線程,且非核心線程數無限大的線程池。
好了簡單瞭解了executorService咱們返回來接着看下executeOn,
在executeOn中調用了executorService.execute(this),executeOn是AsyncCall內部的函數而AsyncCall是一個線程類因此該操做會執行線程的run方法,這裏具體來講就是NamedRunnable的run方法,咱們知道在這個run方法中調用了execute()方法,execute()咱們上面分析過了跟同步請求過程同樣鏈式調用攔截器最終獲取respone。
void executeOn(ExecutorService executorService) { assert (!Thread.holdsLock(client.dispatcher())); boolean success = false; try { executorService.execute(this);//實際執行call success = true; } catch (RejectedExecutionException e) { InterruptedIOException ioException = new InterruptedIOException("executor rejected"); ioException.initCause(e); transmitter.noMoreExchanges(ioException); responseCallback.onFailure(RealCall.this, ioException); } finally { if (!success) { client.dispatcher().finished(this); // This call is no longer running! } } }
至此異步請求流程也分析完了。
最後咱們來總結下Okhttp的請求流程: 首先無論同步仍是異步都會先初始化一個OkhttpClient以後是Request、Call。 不一樣之處在於同步請求把請求添加到runningSyncCalls 而後直接調用execute,鏈式調用攔截器獲取respone並返回。異步請求則是把請求先添加到readyAsyncCalls,以後執行的時候再把其添加到runningAsyncCalls而且把請求放到子線程中取執行,即鏈式調用攔截器獲取respone是在子線程中完成的。 還有就是不論是同步仍是異步請求完成後都會把Call移除。 以上只是Okhttp最簡單的流程分析,其實Okhttp還有不少值得咱們學習的地方,以後我會繼續更新相關內容來更深刻了解Okhttp。