前言
OKHttp是square這個牛叉到帥的一塌糊涂的公司搞的一個網絡請求解決方案,github地址:square/okhttp,有多牛叉不多說,Google最新的sdk中已經替換掉HttpClient相關API了的。
網絡請求基本workflow
直接先上圖吧
來我們看圖說話吧,無論是哪個HTTP開源庫還是自己折騰封裝的網絡庫都可以抽象的看出上面的流程圖,發送一次請求無非一下幾步
1.build request(API參數配置)
2.executor(這里可以有很多變體,比如有無隊列,進出順序,線程管理)
3.parse callback(解析數據,返回T給上層)
OKHttp的workflow
OKHttp再牛叉workflow也無非如此,還是先上圖吧
看上圖說話,即使沒用過OKHttp看完此圖也能大概寫出如何使用它的偽代碼來
val client = OkHttpClient.Builder.build()
val request = Request("url",.....)
val response = client.newCall(request).execute()
好,那我們看看實際代碼是什么樣子的
wow~nice.跟剛才寫的偽代碼幾乎差不多~,所以一個框架封裝的好壞,直接決定是否受人喜歡。流程圖越清楚,閱讀起來更容易。
好了言歸正傳不扯淡了的,來看具體實現吧。
1.OkHttpClient
OkHttp的門面,一個好的框架,幾乎都流行這么干,比如Android-Universal-Image-Loader,Glide等,都是采用門面模式,更加好記憶一些,自己寫功能模塊的時候也經常會寫類似***Manager之類的。負責基本的配置builder,對外API等。
2.RealCall
顧名思義,真正的call,什么鬼,難道還有假的call?
看剛才給的代碼中,client.newCall(request) 這里有一個call,我們看一下OkHttpClient源碼
OkHttpClient實現了Call.Factory的newCall接口,根據request創建RealCall。RealCall為具體的Call實現。RealCall有兩個對外的核心方法,一種是同步直接返回結果的execute,另一種是入列處理的enqueue。
execute的代碼,紅色部分就是執行了一個處理,獲取得到response
enqueue的代碼,與execute不同的是這里是放到了一個叫做dispatch中去處理了的
簡單提一句,new AsyncCall,這個類,不難推斷就是一個Runnable,在run里面調用和execute一樣的網絡處理拿到response,然后responseCallback回去,這里就不做展開了的。
3.Dispatcher
顧名思義,分發,就是請求task的線程管理咯,展開代碼頭部,就一目了然了的。負責維護隊列用的。把剛才的AsyncCall根據當前的策略加入到隊列中去執行。具體實現也離不開ExecutorService。
小結一下
OkHttpClient實現Call.Factory,負責為Request創建Call;RealCall為具體的Call實現,其enqueue()異步接口通過Dispatcher利用ExecutorService實現,而最終進行網絡請求時和同步execute()接口一致,都是通過getResponseWithInterceptorChain()函數實現;
小小的想法
文章看到這里,我只是簡單拆了最表層的workflow,幾個核心類,但是耗時的操作最外層都是這樣的,你可以幾乎只需要換掉getResponseWithInterceptorChain這里的返回response,改為bitmap,ok,他就成了傳說中的imageLoader了的,換成其他的業務需求,返回對應的業務的taskResponse即可輕松搞定.這種workflow已經是一個成熟的耗時操作框架的三部曲了的。