進階android,OKhttp源碼分析——同步請求的源碼分析android
OKhttp是咱們常常用到的框架,做爲開發者們,咱們不僅僅要學會靈活使用,還要知道他的源碼是如何設計的。面試
今天咱們來分析一下OKhttp 同步請求的執行流程和源碼分析緩存
so,老樣子,咱們先來一張圖網絡
從上圖能夠看出,無論是同步請求仍是異步請求,咱們都須要建立一個OKhttpClient對象,用到的是build構造者模式,建立Request對象,而後再OKhttpClient的newCall方法和Request來封裝咱們的call對象。建立咱們的實際請求的call對象,從上圖能夠看到,對於同步請求,咱們調用的是excute方法,異步請求調用的是equeue方法。框架
咱們看一下作簡單使用異步
OkHttpClient okHttpClient = new OkHttpClient.Builder() .readTimeout(10, TimeUnit.SECONDS) .build(); Request request = new Request.Builder().url("https://blog.csdn.net/androidstarjack").build(); Call call = okHttpClient.newCall(request); try { call.execute();//同步請求 call.enqueue(new Callback() {//異步請求 @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { } }); } catch (IOException e) { e.printStackTrace(); }
咱們先看一下okhttp的build ide
首先咱們經過源碼能夠看出,okhttp的建立時經過build方法來建立的,其中初始化了一些事情,好比建立一個dispatcher攔截器,和一個鏈接池,鏈接池只要是連接狀態的保存以及複用。build是要是建立 okhttp是所須要的參數。源碼分析
在建立Request建立的時候也是用構造者模式進行建立的,源碼以下:ui
Builder(Request request) { this.url = request.url; this.method = request.method; this.body = request.body; this.tag = request.tag; this.headers = request.headers.newBuilder(); }
request的build構造裏面初始化了一些請求的URL,請求方法哈請求頭等請求報文的一些信息。this
Call對象 是經過他的父親RealCall來完成的。
Call對象持有了Okhttp 和Request兩個對象,同時呢還建立了一個緩存攔截器RetryAndFollowUpInterceptor,用於所須要的重定向操做。
經過調用okhttpClient的newCAll來完成CALL的新建,進行相應的操做
緊接着調用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); } }
//布爾值executed表示一個okhttp請求只能運行執行一次,而後開啓捕捉一些錯誤堆棧信息,點用一個eventListener監聽方法,
接卸來是調用分發器的executed方法。這纔是重中之重。
... client.dispatcher().executed(this); ...
client.dispatcher返回一個分發器。而後經過分發器來執行操做:
在同步請求中,調用executed方法,很簡單酒吧這個Call對象添加到隊列當中。
Dispatcher的做用主要是維持call請求發給他 的狀態,同時維護了一個線程池,開啓了網絡請求。
從源碼中咱們能夠看到Dispatcher
這幾個請求隊列表明着不一樣狀態下的請求狀況。
緊接着經過攔截器鏈依次調用執行操做。
最後還調用了Finish方法
注意第三個參數,爲false,這個方法的主要做用就是移除當前的請求,若是不能移除的話,返回異常,咱們能夠注意到,同步請求不須要調用promoteCalls,只有在異步請求的時候纔會調用到,這個方法之後咱們在講。
最後判斷,正在將要執行的請求隊列集合爲0而且閒調用的回調不爲null時,調用其run方法。此時,同步方法執行完成。
若是對技術開發比較感興趣,歡迎關注公衆號:終端研發部。一塊兒交流技術,進階!