okHttp小結

by hzwusibo? 20190504


常見問題一:簡述一下OkHttp

OkHttp已被谷歌加入到Android的源碼中。目前比較流行的Retrofit也是默認使用OkHttp的关拒。

支持http2沛豌,對一臺機器的所有請求共享同一個socket

內(nèi)置連接池,支持連接復用啃炸,減少延遲

支持透明的gzip壓縮響應體

通過緩存避免重復的請求

請求失敗時自動重試主機的其他ip铆隘,自動重定向

好用的API

關于 HTTP2 和 HTTPS,這些你必須要知道

http://www.reibang.com/p/bf1db5c4d2d2

常見問題二:看過OkHttp的源碼嗎南用,簡單說一下

(一)膀钠、總體設計

第一,通過一個構建者模式(Request.Builder)構建所有的request裹虫;然后分發(fā)到Dispatcher(分發(fā)器)肿嘲;

第二,Dispatcher再把request分發(fā)到HttpEngine(真正干活的類)中筑公,HttpEngine首先要看一下本次請求有沒有cache(緩存)雳窟,如果有緩存,就從緩存中拿到信息匣屡,然后返回給response封救;如果沒有緩存拇涤,HttpEngine就把request分發(fā)到ConnectionPool(連接池)中;

第三誉结,在ConnectionPool(連接池)中鹅士,通過Connection發(fā)送請求,通過Route(路由)和Platfrom(平臺)惩坑,到達Server(Socket),獲取到Data如绸,然后返回response。

(二)旭贬、流程圖

上面是OKHttp總體設計圖怔接,主要是通過Diapatcher不斷從RequestQueue中取出請求(Call),根據(jù)是否已緩存調(diào)用Cache或Network這兩類數(shù)據(jù)獲取接口之一稀轨,從內(nèi)存緩存或是服務器取得請求的數(shù)據(jù)扼脐。該引擎有同步和異步請求,同步請求通過Call.execute()直接返回當前的Response奋刽,而異步請求會把當前的請求Call.enqueue添加(AsyncCall)到請求隊列中瓦侮,并通過回調(diào)(Callback)的方式來獲取最后結果。

OkHttp使用教程

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html

Dispatcher線程池總結

1)調(diào)度線程池Disptcher實現(xiàn)了高并發(fā)佣谐,低阻塞的實現(xiàn)?

2)采用Deque作為緩存肚吏,先進先出的順序執(zhí)行?

3)任務在try/finally中調(diào)用了finished函數(shù),控制任務隊列的執(zhí)行順序狭魂,而不是采用鎖罚攀,減少了編碼復雜性提高性能。

Android面試題-OkHttp3源碼分析

https://blog.csdn.net/mwq384807683/article/details/71173442?locationNum=8&fps=1

OkHttp通過定義許多攔截器一步一步地對Request進行攔截處理雌澄,直到請求返回網(wǎng)絡數(shù)據(jù)斋泄,后面又倒過來,一步一步地對Response進行攔截處理镐牺,最后攔截的結果就是回調(diào)的最終Response炫掐。

RealInterceptorChain的proceed方法,通過順序地傳入一個攔截器的集合睬涧,創(chuàng)建一個RealInterceptorChain募胃,然后拿到之前OkHttp創(chuàng)建的各種攔截器,并調(diào)用其interrupt方法畦浓,并返回Response對象痹束。其調(diào)用順序如下:

1)在配置 OkHttpClient 時設置的 interceptors;

2)負責失敗重試以及重定向的 RetryAndFollowUpInterceptor宅粥;

3)負責把用戶構造的請求轉換為發(fā)送到服務器的請求参袱、把服務器返回的響應轉換為用戶友好的響應的 BridgeInterceptor;

4)負責讀取緩存直接返回、更新緩存的 CacheInterceptor抹蚀;

5)負責和服務器建立連接的 ConnectInterceptor剿牺;

6)配置 OkHttpClient 時設置的 networkInterceptors;

7)負責向服務器發(fā)送請求數(shù)據(jù)环壤、從服務器讀取響應數(shù)據(jù)的 CallServerInterceptor晒来。

OkHttp的這種攔截器鏈采用的是責任鏈模式,這樣的好處是將請求的發(fā)送和處理分開郑现,并且可以動態(tài)添加中間的處理方實現(xiàn)對請求的處理湃崩、短路等操作

責任鏈模式是一種對象的行為模式。在責任鏈模式里接箫,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈攒读。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求辛友。發(fā)出這個請求的客戶端并不知道鏈上的哪一個對象最終處理這個請求薄扁,這使得系統(tǒng)可以在不影響客戶端的情況下動態(tài)地重新組織和分配責任。

可以看到 OkHttp 的線程池配置如下:

核心線程數(shù):0

最大線程數(shù):Iteger.MAX_VALUE废累,其實就是不限制

空閑線程保活時間:60s

任務隊列:SynchronousQueue邑滨,為有界隊列,且隊列大小為 0匣距,不存 Runnable,只是用來進行生產(chǎn)者和消費者之間的傳遞任務乙各。

是不是很眼熟墨礁?和我們在 Executors 使用的 緩存線程池的配置完全一樣耳峦,緩存線程池的代碼如下:

? ? public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {

? ? ? ? return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 60L, TimeUnit.SECONDS,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new SynchronousQueue<Runnable>(),

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? threadFactory);

? ? }

所以 OkHttp 自己創(chuàng)建的這個線程池焕毫,和緩存線程池的區(qū)別蹲坷,僅僅是修改了線程名。

我們簡要分析一下緩存線程池的運行機制邑飒,進入到 ThreadPoolExecutor 中的execute方法的源碼中循签,假設線程池處于運行狀態(tài),會有這樣的流程:

新過來一個任務县匠,由于核心線程數(shù)為 0,不需要創(chuàng)建核心線程汹来,所以嘗試加入任務隊列

如果線程池中有線程剛好空閑可以接收任務,因為任務隊列的類型是 SynchronousQueue兰粉,實際大小為 0,只做消費者和生產(chǎn)者的中轉站玖姑,所以這時候,就可以入列成功焰络,通過 SynchronousQueue 中轉任務給空閑的線程執(zhí)行。

如果當前線程池所有線程工作飽和甜孤,會入列失敗。這時候 ThreadPoolExecutor 會調(diào)用addWorker(command, false)來創(chuàng)建并且啟動新線程课蔬。

這樣子郊尝,就會產(chǎn)生疑問,那么如果一次性同時發(fā)起大量的請求流昏,不就會產(chǎn)生大量線程了?比如我一次性發(fā)起 100 個請求谚鄙,那么是不是會發(fā)出 100 個線程刁绒?

是的闷营,如果直接使用該線程池而沒有其他的策略的話知市,是有這樣的問題。

所以在 OkHttp 中線程池只是一個輔助作用嫂丙,僅僅是用來做線程緩存娘赴,便于復用的。真正對這些請求的并發(fā)數(shù)量限制跟啤,執(zhí)行時機等等都是調(diào)度器 Dispatcher 承擔的诽表。在 OkHttp 這里,線程池只是個帶緩存功能的執(zhí)行器袄简,而真正的調(diào)度是外部包了一個調(diào)度策略的议双。

https://www.cnblogs.com/hankzhouAndroid/p/8710284.html

Retrofit

OkHttp和Retrofit的聯(lián)系

http://www.reibang.com/p/4d67fe493ebf

Retrofit負責請求的數(shù)據(jù)和請求的結果,使用接口的方式呈現(xiàn)(注解)汞舱。

OkHttp負責請求的過程宗雇。

RxJava負責異步,各種線程之間的切換赔蒲。

Retrofit是Square開源的一款適用于Android網(wǎng)絡請求的框架。Retrofit底層是基于OkHttp實現(xiàn)的欢际,與其他網(wǎng)絡框架不同的是矾兜,它更多使用運行時注解的方式提供功能。

1.Retrofit優(yōu)缺點

優(yōu)點:

?? 可以配置不同HTTP client來實現(xiàn)網(wǎng)絡請求椅寺,如okhttp、httpclient等桐玻;

?? 請求的方法參數(shù)注解都可以定制荆萤;

?? 支持同步、異步和RxJava链韭;

?? 解耦;

?? 可以配置不同的反序列化工具來解析數(shù)據(jù),如json州邢、xml等褪子;

?? 使用非常方便靈活骗村;

2.Retrofit注解

Retrofit注解分為三大類胚股,分別是HTTP請求方法注解(8種)、標記類注解(3種)和參數(shù)類注解(11種)琅拌。

??HTTP請求方法注解:GET、POST刻坊、PUT党晋、DELETE谭胚、PATCH未玻、HEAD、OPTIONS旁趟、HTTP

??標記類注解:FormUrlEncoded舞终、Multipart、Streaming

??參數(shù)類注解:Headers敛劝、Header、Body蛾方、Field上陕、FieldMap、Part释簿、PartMap、Path煮纵、Query、QueryMap行疏、Url

Retrofit底層對網(wǎng)絡的訪問默認是基于okhttp,不過Retrofit非常適合于restful url格式的請求终息,更多使用注解的方式提供功能贞让。

Retrofit框架網(wǎng)絡請求流程圖

網(wǎng)絡請求:APP發(fā)起網(wǎng)絡請求,Retrofit通過注解配置請求參數(shù)休傍、Header、Url之后磨取,通過OkHttp發(fā)生網(wǎng)絡請求給服務器柴墩。

服務器響應:服務器返回響應數(shù)據(jù),OkHttp將數(shù)據(jù)傳遞給Retrofit江咳,再把數(shù)據(jù)直接傳遞給APP,界面刷新反饋結果給用戶歼指。

OkHttp和Retrofit都是網(wǎng)絡開源框架,但是他們之間的區(qū)別請不要混淆:

職責不同:

??Retrofit主要負責應用層面的封裝胀茵,就是說主要面向開發(fā)者挟阻,方便使用,比如請求參數(shù)附鸽,響應數(shù)據(jù)的處理,錯誤處理等等熄浓。

??OkHttp主要負責socket部分的優(yōu)化省撑,比如多路復用谎柄,buffer緩存惯雳,數(shù)據(jù)壓縮等等鸿摇。

封裝不同:

??Retrofit封裝了具體的請求,線程切換以及數(shù)據(jù)轉換拙吉。

??OkHttp 是基于Http協(xié)議封裝的一套請求客戶端,雖然它也可以開線程往史,但根本上它更偏向真正的請求佛舱,跟HttpClient, HttpUrlConnection的職責是一樣的。

網(wǎng)上一般都推薦RxJava+Retrofit+OkHttp框架请祖。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肆捕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子慎陵,更是在濱河造成了極大的恐慌,老刑警劉巖捏悬,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胆筒,死亡現(xiàn)場離奇詭異,居然都是意外死亡抒和,警方通過查閱死者的電腦和手機彤蔽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來镊辕,“玉大人,你說我怎么就攤上這事征懈。” “怎么了鬼悠?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵亏娜,是天一觀的道長。 經(jīng)常有香客問我它掂,道長溯泣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任熟妓,我火速辦了婚禮栏尚,結果婚禮上,老公的妹妹穿的比我還像新娘译仗。我一直安慰自己,他們只是感情好阐污,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布咱圆。 她就那樣靜靜地躺著,像睡著了一般序苏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上围来,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天,我揣著相機與錄音桶错,去河邊找鬼胀蛮。 笑死,一個胖子當著我的面吹牛醇滥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼不跟,長吁一口氣:“原來是場噩夢啊……” “哼米碰!你這毒婦竟也來了?” 一聲冷哼從身側響起吕座,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漆诽,沒想到半個月后锣枝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡供鸠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年陨闹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寨闹。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡觅廓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情矮瘟,我是刑警寧澤塑娇,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站哨啃,受9級特大地震影響写妥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜珍特,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望莱找。 院中可真熱鬧嗜桌,春花似錦、人聲如沸骨宠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棕所。三九已至,卻和暖如春琳省,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背击费。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工桦他, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓垃瞧,卻偏偏與公主長得像坪郭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嗦锐,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356

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