【Android知識(shí)點(diǎn)總結(jié)系列】之OkHttp原理總結(jié)

很久之前看過 OkHttp 的源碼盗忱,但當(dāng)時(shí)沒有做總結(jié),今天突然想在腦海中過一遍OkHttp 內(nèi)部的執(zhí)行流程時(shí)并齐,發(fā)現(xiàn)一片混沌不知從何說起妖泄,于是今天重新過了一遍驹沿,參考了一篇從源碼角度進(jìn)行解析的文章并做了總結(jié),需要詳細(xì)源碼解讀的可以去看看這篇文章蹈胡,這里只做總結(jié)渊季,不重復(fù)造輪子,網(wǎng)上詳細(xì)解析OkHttp 的優(yōu)秀文章也很多罚渐。

先看一張流程圖(來自這篇文章),另外推薦博主的另一篇Retrofit解讀

OkHttp原理圖
整體流程:

整個(gè)流程是却汉,通過OkHttpClientnewCall() 將構(gòu)建的 Request轉(zhuǎn)換為 CallCall 內(nèi)部調(diào)用 RealCall荷并,然后在RealCall 中進(jìn)行異步或同步任務(wù)合砂,最后通過一系列的攔截器 interceptor 發(fā)出網(wǎng)絡(luò)請(qǐng)求和得到返回的 response

1 具體執(zhí)行流程:

整個(gè)請(qǐng)求流程是從RealCall開始的:
1.1 如果是同步請(qǐng)求( execute()):

則會(huì)調(diào)用 dispatcherexecuted()方法將請(qǐng)求任務(wù)加到同步請(qǐng)求運(yùn)行隊(duì)列中(即runningSyncCalls.add(call);)然后調(diào)用getResponseWithInterceptorChain(),該方法中通過執(zhí)行一系列的攔截器完成整個(gè)網(wǎng)絡(luò)的請(qǐng)求任務(wù)源织,最后會(huì)調(diào)用dispatcherfinished()方法告知我們執(zhí)行完畢了

1.2 如果是異步請(qǐng)求(enqueue()):

主要用到了調(diào)度器Dispatcher既穆,我們調(diào)用enqueue()方法后,在
RealCall 中會(huì)去調(diào) Dispatcherenqueue() 方法雀鹃,這個(gè)方法會(huì)判斷當(dāng)前的請(qǐng)求數(shù)量從而決定要將該請(qǐng)求添加到等待隊(duì)列還是添加到異步執(zhí)行隊(duì)列中利用線程池去執(zhí)行。

執(zhí)行的時(shí)候調(diào)用的還是getResponseWithInterceptorChain()從而還是通過一系列的攔截器來完成網(wǎng)絡(luò)請(qǐng)求励两,不同的是這里是利用線程池來異步執(zhí)行任務(wù)黎茎。

2 這個(gè)Dispatcher攔截器是什么?:

Dispatcher 在同步請(qǐng)求中的作用只是用于告知我們執(zhí)行狀態(tài)当悔,例如開始執(zhí)行了(調(diào)用executed())以及運(yùn)行結(jié)束了(調(diào)用finished()

其主要作用是在異步執(zhí)行過程中傅瞻,Dispatcherenqueue()
方法會(huì)判斷當(dāng)前的請(qǐng)求數(shù)量從而決定要將該請(qǐng)求添加到等待隊(duì)列還是添加到異步執(zhí)行隊(duì)列中利用線程池去執(zhí)行。任務(wù)的異步執(zhí)行真是在這里完成分配的盲憎。

3 攔截器又是什么嗅骄?

3.1 首先

RealCall中真正發(fā)起網(wǎng)絡(luò)請(qǐng)求以及解析返回結(jié)果的,是getResponseWithInterceptorChain() 饼疙,這個(gè)方法中將一系列的攔截器例如 重定向攔截器溺森、轉(zhuǎn)換攔截器、緩存攔截器、連接攔截器等 添加到一個(gè) ArrayList 后通過一系列的鏈?zhǔn)秸{(diào)用執(zhí)行各個(gè)攔截器;

3.2 具體的攔截器包括:

  • 負(fù)責(zé)失敗重試以及重定向的 RetryAndFollowUpInterceptor屏积;
  • 負(fù)責(zé)把用戶構(gòu)造的請(qǐng)求轉(zhuǎn)換為發(fā)送到服務(wù)器的請(qǐng)求医窿、把服務(wù)器返回的響應(yīng)轉(zhuǎn)換為用戶友好的響應(yīng)的 BridgeInterceptor
  • 負(fù)責(zé)讀取緩存直接返回、更新緩存的 CacheInterceptor(判斷是要去獲取網(wǎng)絡(luò)的Response還是直接使用緩存)炊林;
  • 負(fù)責(zé)和服務(wù)器建立連接的 ConnectInterceptor姥卢;
  • 配置 OkHttpClient時(shí)設(shè)置的 networkInterceptors;
  • 負(fù)責(zé)向服務(wù)器發(fā)送請(qǐng)求數(shù)據(jù)渣聚、從服務(wù)器讀取響應(yīng)數(shù)據(jù)的 CallServerInterceptor独榴。

3.3 總的來說

攔截器是將請(qǐng)求一層一層向下傳,直到有一層能夠得到 Response 就停止并將 Response 向上面的攔截器傳遞奕枝,然后各個(gè)攔截器會(huì)對(duì)Response 進(jìn)行一些處理最后傳到 RealCall 類中返回

Interceptor的設(shè)計(jì)體現(xiàn)了設(shè)計(jì)模式中的單一職責(zé)原則

Interceptor 的設(shè)計(jì)是一種分層的思想棺榔,每個(gè) Interceptor 就是一層。分層簡(jiǎn)化了每一層的邏輯倍权,每層只需要關(guān)注自己的責(zé)任掷豺,而各層之間通過約定的接口/協(xié)議進(jìn)行合作(面向接口編程思想),共同完成復(fù)雜的任務(wù)薄声。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末当船,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子默辨,更是在濱河造成了極大的恐慌德频,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異屈藐,居然都是意外死亡送朱,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門钞护,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人爆办,你說我怎么就攤上這事难咕。” “怎么了距辆?”我有些...
    開封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵余佃,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我跨算,道長(zhǎng)爆土,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任诸蚕,我火速辦了婚禮步势,結(jié)果婚禮上氧猬,老公的妹妹穿的比我還像新娘。我一直安慰自己立润,他們只是感情好狂窑,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著桑腮,像睡著了一般泉哈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上破讨,一...
    開封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天丛晦,我揣著相機(jī)與錄音,去河邊找鬼提陶。 笑死烫沙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的隙笆。 我是一名探鬼主播锌蓄,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼撑柔!你這毒婦竟也來了瘸爽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤铅忿,失蹤者是張志新(化名)和其女友劉穎剪决,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體檀训,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柑潦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了峻凫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渗鬼。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖荧琼,靈堂內(nèi)的尸體忽然破棺而出乍钻,到底是詐尸還是另有隱情,我是刑警寧澤铭腕,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站多糠,受9級(jí)特大地震影響累舷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜夹孔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一被盈、第九天 我趴在偏房一處隱蔽的房頂上張望析孽。 院中可真熱鬧,春花似錦只怎、人聲如沸袜瞬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)邓尤。三九已至,卻和暖如春贴谎,著一層夾襖步出監(jiān)牢的瞬間汞扎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工擅这, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留澈魄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓仲翎,卻偏偏與公主長(zhǎng)得像痹扇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子溯香,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • OkHttp源碼的samples的簡(jiǎn)單使用的示例: public static void main(String....
    _warren閱讀 760評(píng)論 0 1
  • OkHttp解析系列 OkHttp解析(一)從用法看清原理OkHttp解析(二)網(wǎng)絡(luò)連接OkHttp解析(三)關(guān)于...
    Hohohong閱讀 20,982評(píng)論 4 58
  • 這篇文章主要講 Android 網(wǎng)絡(luò)請(qǐng)求時(shí)所使用到的各個(gè)請(qǐng)求庫(kù)的關(guān)系鲫构,以及 OkHttp3 的介紹。(如理解有誤逐哈,...
    小莊bb閱讀 1,166評(píng)論 0 4
  • 關(guān)于okhttp是一款優(yōu)秀的網(wǎng)絡(luò)請(qǐng)求框架芬迄,關(guān)于它的源碼分析文章有很多,這里分享我在學(xué)習(xí)過程中讀到的感覺比較好的文章...
    蕉下孤客閱讀 3,605評(píng)論 2 38
  • 《Linux系統(tǒng)移植(第2版)》分為4篇昂秃。第1篇 簡(jiǎn)單介紹了Linux內(nèi)核和嵌入式Linux系統(tǒng)開發(fā)環(huán)境搭建禀梳; 第...
    JosephDHF閱讀 1,046評(píng)論 0 1