马会一肖中特资料一肖中特:淺談OkHttp以及Retrofit+RxJava的封裝使用 [復制鏈接]

2019-5-22 10:07
少年夢 閱讀:383 評論:0 贊:0
Tag:  

1.為什么我們要使用OkHttp?OkHttp有什么優點?

致富之地一肖中特 www.qcfmo.icu 說OkHttp之前我們先說另外兩個網絡請求庫——HttpUrlConnection和HttpClient。在沒有OkHttp之前的日子里,他們才是Android用來完成網絡請求的類庫。那么這兩者都有什么優缺點呢? 為什么不再繼續使用下去呢?

HttpClient是Apache基金會的一個開源網絡庫, 功能十分強大, API數量眾多, 但是正是由于龐大的API數量使得我們很難在不破壞兼容性的情況下對它進行升級和擴展, 所以Android團隊在提升和優化HttpClient方面的工作態度并不積極。

HttpURLConnection是一種多用途, 輕量極的HTTP客戶端, 提供的API比較簡單, 可以容易地去使用和擴展. 不過在Android 2.2版本之前,HttpURLConnection一直存在著一些令人厭煩的bug. 比如說對一個可讀的InputStream調用close()方法時,就有可能會導致連接池失效了。

因此, 一般的推薦是在2.2之前, 使用HttpClient, 因為其bug較少. 在2.2之后, 推薦使用HttpURLConnection, 因為API簡單, 體積小, 并且有壓縮和緩存機制, 但是在4.4以后Android團隊已經把網絡請求庫更換為OkHttp了。

那么到底OkHttp相比于HttpUrlConnection和HttpClient好在哪里呢?先上個權威、專業的百度百科的介紹。

圖片描述

OkHttp的優點:

1.支持Http/1.1 Http/2 網絡協議

2.支持GZIP, 可以壓縮下載體積

3.響應緩存可以直接避免重復請求

4.高效、靈活;通過連接池,減少了請求延遲

5.共享Socket,減少對服務器的請求次數

綜上所述,OkHttp是一個吊炸天的網絡請求庫,如果你用過它,就會慢慢地愛上它。

2.OkHttp怎么用?為什么推薦Retrofit+RxJava這種方式?

關于OkHttp的使用,我想絕大多數使用過這個請求庫的老鐵,都沒有直接拿來用的,一般都會選擇封裝一下,再拿來使用,網上對OkHttp的封裝有很多,這里就不多加介紹了。

雖然網上有很多的OkHttp封裝庫,但是我仍然強烈推薦Retrofit+RxJava這種方式進行網絡請求。理由有兩點:

第一點:靈活。Retrofit是一個基于Restful的網絡請求庫,自身對OkHttp進行了封裝,支持URL動態變化,所以我們完全可以在Retrofit的基礎上再次對OkHttp進行簡單的封裝,比如封裝一個OkHttpInterceptor等等。

第二點:鏈式編程。其實這個也是用Retrofit核心點了,可能很多人對鏈式編程并不感冒,但是這種編程風格一定會越來越火,因為鏈式編程讓邏輯變得更加簡潔(注意是邏輯而不是代碼),增加了代碼的可讀性。同時Retrofit支持了RxJava這個優雅的異步請求庫(后面我會出一篇文章專門講這個庫),與其組成了完美的技術CP,讓我們的代碼變得簡潔、優雅。

3.Retrofit+RxJava如何使用?(本文重點)首先引入Retrofit和RxJava

>

complie "com.squareup.retrofit2:retrofit:2.1.0"

complie "com.squareup.retrofit2:converter-scalars:2.1.0"

complie "com.squareup.retrofit2:converter-gson:2.1.0"

complie "com.squareup.retrofit2:adapter-rxjava2:2.2.0"

complie "io.reactivex.rxjava2:rxjava:2.0.6"

compile "io.reactivex.rxjava2:rxandroid:2.0.1"

好了,萬事俱備,我們下面開始對Retrofit+RxJava進行簡單地封裝。在封裝之前,我們先思考一個問題,就是一個好的網絡請求框架是什么樣的?首先,你必須得有request和response打印log吧,如果沒有的話,萬一接口出問題了,你咋跟后臺的大哥對接;其次,你得有緩存的處理,哪怕在沒有網絡的情況下也不能顯示一個空白吧;最后就是可以不用操心地把數據流轉換成對象,方便我們使用?;諞隕峽悸?,我們開始封裝。

request和response的信息我們都可以在public Response intercept(Chain chain) 里面的chain對象獲取,所以我們可以自定義一個OkHttpInterceptor繼承Interceptor,在這里面為所欲為。The talk is cheap,show me the code。

上代碼!

圖片描述

具體的代碼我會在文章最后貼上我的github地址里面有詳細的實現過程,但是這里面有一些坑,我必須強調一下。在通過 Response response=chain.proceed(requesrt);拿到response對象的時候,不能直接調用response.body().string(),因為調用該方法后數據流就關閉,程序就可能會發生異常。為啥流會關閉呢?我們看一下response.body().string()的源碼

圖片描述

在finally里Util.closeQuietly(source),這里會關閉我們在內存里的資源,導致程序異常,所以這里我們不能直接調用response.body().string(),而是需要創建出一個新的ResponseBody給應用層調用,ResponseBody body=response.peekBody(10241024);if (body!=null){Log.e(TAG,"protocol: "+body.string());} ,這時候你肯定又要問了為啥你這時候body.string()調用關閉流就沒事了,原因就在于我們請求接口返回的數據流都會放在內存里,而response.peekBody(10241024)這種創建的body對面的數據流并沒有放在內存里,所以Util.closeQuietly(source)就不會造成異常,可以看一下下面的圖。

圖片描述

另外關于緩存的問題這里要再說一下,我們在網絡可連接的情況不使用緩存,但是在無網絡的情況下使用緩存,但是你可能會發現,當用POST請求的時候依然沒有緩存,此時你可能會懷疑自己是不是用錯了方法?不,你沒有,因為OkHttp的緩存就是不支持POST的請求方式,我們看一下Cache的源碼.

圖片描述

OkHttp認為post請求是個多變快速的請求,沒有給這種請求設置緩存,如果你一定要緩存那么就用sqlite吧!

完成log的輸出和緩存的設置,最后就是單例OkHttpClient對象,結合Retrofit和RxJava的使用了。

圖片描述

圖片描述

別忘了創建接口,聲明請求方法,@GET是請求方式,()里面是接口地址,會跟在Retrofit里的baseUrl里的地址拼成完整的地址。

圖片描述

最后我們看看使用的效果

圖片描述

圖片描述


我來說兩句
您需要登錄后才可以評論 登錄 | 立即注冊
facelist
所有評論(0)
領先的中文移動開發者社區
18620764416
7*24全天服務
意見反?。[email protected]

掃一掃關注我們

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 致富之地一肖中特 )