Okhttp同步请求源码分析
進(jìn)階android,OKhttp源碼分析——同步請(qǐng)求的源碼分析
OKhttp是我們經(jīng)常用到的框架,作為開(kāi)發(fā)者們,我們不單單要學(xué)會(huì)靈活使用,還要知道他的源碼是如何設(shè)計(jì)的。
今天我們來(lái)分析一下OKhttp 同步請(qǐng)求的執(zhí)行流程和源碼分析
so,老樣子,我們先來(lái)一張圖
從上圖可以看出,不管是同步請(qǐng)求還是異步請(qǐng)求,我們都需要?jiǎng)?chuàng)建一個(gè)OKhttpClient對(duì)象,用到的是build構(gòu)造者模式,創(chuàng)建Request對(duì)象,然后再OKhttpClient的newCall方法和Request來(lái)封裝我們的call對(duì)象。創(chuàng)建我們的實(shí)際請(qǐng)求的call對(duì)象,從上圖可以看到,對(duì)于同步請(qǐng)求,我們調(diào)用的是excute方法,異步請(qǐng)求調(diào)用的是equeue方法。
我們看一下做簡(jiǎn)單使用
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();//同步請(qǐng)求call.enqueue(new Callback() {//異步請(qǐng)求@Overridepublic void onFailure(Call call, IOException e) {}@Overridepublic void onResponse(Call call, Response response) throws IOException {}});} catch (IOException e) {e.printStackTrace();}復(fù)制代碼我們先看一下okhttp的build
首先我們通過(guò)源碼可以看出,okhttp的創(chuàng)建時(shí)通過(guò)build方法來(lái)創(chuàng)建的,其中初始化了一些事情,比如創(chuàng)建一個(gè)dispatcher攔截器,和一個(gè)連接池,連接池只要是鏈接狀態(tài)的保存以及復(fù)用。build是要是創(chuàng)建 okhttp是所需要的參數(shù)。
在創(chuàng)建Request創(chuàng)建的時(shí)候也是用構(gòu)造者模式進(jìn)行創(chuàng)建的,源碼如下:
Builder(Request request) {this.url = request.url;this.method = request.method;this.body = request.body;this.tag = request.tag;this.headers = request.headers.newBuilder();} 復(fù)制代碼request的build構(gòu)造里面初始化了一些請(qǐng)求的URL,請(qǐng)求方法哈請(qǐng)求頭等請(qǐng)求報(bào)文的一些信息。
Call對(duì)象 是通過(guò)他的父親RealCall來(lái)完成的。
Call對(duì)象持有了Okhttp 和Request兩個(gè)對(duì)象,同時(shí)呢還創(chuàng)建了一個(gè)緩存攔截器RetryAndFollowUpInterceptor,用于所需要的重定向操作。
通過(guò)調(diào)用okhttpClient的newCAll來(lái)完成CALL的新建,進(jìn)行相應(yīng)的操作
緊接著調(diào)用execute方法來(lái)完成同步請(qǐng)求!
@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);}}復(fù)制代碼//布爾值executed表示一個(gè)okhttp請(qǐng)求只能運(yùn)行執(zhí)行一次,然后開(kāi)啟捕捉一些錯(cuò)誤堆棧信息,點(diǎn)用一個(gè)eventListener監(jiān)聽(tīng)方法, 接卸來(lái)是調(diào)用分發(fā)器的executed方法。這才是重中之重。
...client.dispatcher().executed(this); ...復(fù)制代碼client.dispatcher返回一個(gè)分發(fā)器。然后通過(guò)分發(fā)器來(lái)執(zhí)行操作:
在同步請(qǐng)求中,調(diào)用executed方法,很簡(jiǎn)單酒吧這個(gè)Call對(duì)象添加到隊(duì)列當(dāng)中。
Dispatcher的作用主要是維持call請(qǐng)求發(fā)給他 的狀態(tài),同時(shí)維護(hù)了一個(gè)線程池,開(kāi)啟了網(wǎng)絡(luò)請(qǐng)求。
從源碼中我們可以看到Dispatcher
這幾個(gè)請(qǐng)求隊(duì)列代表著不同狀態(tài)下的請(qǐng)求情況。
緊接著通過(guò)攔截器鏈依次調(diào)用執(zhí)行操作。 最后還調(diào)用了Finish方法
注意第三個(gè)參數(shù),為false,這個(gè)方法的主要作用就是移除當(dāng)前的請(qǐng)求,如果不能移除的話(huà),返回異常,我們可以注意到,同步請(qǐng)求不需要調(diào)用promoteCalls,只有在異步請(qǐng)求的時(shí)候才會(huì)調(diào)用到,這個(gè)方法以后我們?cè)谥v。
最后判斷,正在將要執(zhí)行的請(qǐng)求隊(duì)列集合為0并且閑調(diào)用的回調(diào)不為null時(shí),調(diào)用其run方法。此時(shí),同步方法執(zhí)行完成。
2018年技術(shù)文章匯總
NDK項(xiàng)目實(shí)戰(zhàn)—高仿360手機(jī)助手之卸載監(jiān)聽(tīng)
(Android)面試題級(jí)答案(精選版)
如果對(duì)技術(shù)開(kāi)發(fā)比較感興趣,歡迎關(guān)注公眾號(hào):終端研發(fā)部。一起交流技術(shù),進(jìn)階!
總結(jié)
以上是生活随笔為你收集整理的Okhttp同步请求源码分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JavaScript基础总结(五)——M
- 下一篇: “小罐茶大师作”20亿元销售额难掩虚假宣