當前位置:
首頁 > 最新 > 網路庫Retrofit2原理簡析

網路庫Retrofit2原理簡析

之前我們分析過了Okhttp這個優秀的網路請求庫,但是在實際的使用時,還是會覺得有很多的不方便,你會發現它跟HttpUrlConnection,或者HttpClient一樣,是一個比較底層的網路請求庫,處理的是底層的網路請求和響應的問題。而我們在業務中要處理上層的邏輯,比如響應內容解析,方便的API實現等,這都需要我們對它進行重新封裝,以適合我們特定的業務邏輯。那有沒有比較簡潔,方便,優雅的封裝方式來封裝Okhttp的使用呢,Square早以為我們考慮了這個問題,於是配套Okhttp,推出了Retrofit作為上層的網路請求庫。Retrofit是Okhttp高效化封裝之後的產物,雖然它之前也是可以定義使用其他底層網路庫的(在Retrofit2之後去除了這個擴展)。在後面漸漸形成了Retrofit+Okhttp+RxJava網路請求三劍客的趨勢。

Retrofit優點

那麼Retrofit的優點是什麼?(哈哈,沒有優點,我憑什麼使用它)

一句話概括就是它以優秀的設計思想讓我們能以輕鬆簡潔的方式進行網路數據的請求。

Retrofit使用方式

接下來我們用一個簡單的例子來看看它是如何處理的。

1.定義Bean類,代表請求數據的類型。

2.定義一個API請求介面,裡面包括要訪問的Restful api請求。

就是先定義一個介面,然後將開發文檔中的一個REST API對應的寫一個方法,在方法上加上註解,在方法參數上加上註解,返回值返回Call或者Observable,泛型類型為該數據解析之後的bean類型。這樣一個請求介面就完成了。

3.獲取Retrofit客戶端對象。

創建一個Retrofit對象,對其進行初始化配置,這裡可以對OkHttpClient對象進行配置,比如添加日誌攔截,緩存設置,超時設置等,對Retrofit對象可以對CallAdapterFactory調用適配器和ConverterFactory響應數據解析器進行配置。

4.創建請求介面對象,調用響應的API方法。

這是配合RxJava的使用方式,調用了getLastDaily方法請求數據,指定了請求在其他線程執行,響應回到主線程,成功響應到callBack.onSuccess(joke); 網路請求錯誤到callBack.onFailure(throwable);

在層次上來看,其實就是獲取一個配置好的Retrofit客戶端,然後根據配置好的RequestApi介面創建RequestApi對象,調用其中的某個API方法,然後採用RxJava的方式就可以完成一次網路數據的請求和解析處理了。我們再對其進行適合封裝,會發現使用起來超級方便。

Retrofit整體架構

那麼Retrofit內部是如何實現的,整體流程是怎麼樣的呢?在這裡引用一張圖讓大家有Retrofit結構一個大體的了解。

Retrofit類分析

Retrofit使用建造者模式來創建對象,這樣可以方便在創建Retrofit之前就對其進行一次性相應的配置。既然是採用建造者模式,裡面必定是涉及一系列屬性的設置,我們直接看看它的屬性和內部Build構造方法。

Retrofit創建介面對象

接下來我們分析Retrofit是如何根據定義的介面創建響應的可執行對象的。

可以看到,Retrofit是使用動態代理的方式創建了一個實現service介面的對象,當外部調用service介面方法,會調用invoke方法,然後載入當前方法對應的處理方式ServiceMethod,和創建原始的OkHttpCall,用於內部使用Okhttp去執行真正的網路請求,然後再將OkHttpCall對象封裝轉換成另一種類型的對象。

ServiceMethod的創建

接下來我們分析ServiceMethod做了什麼。它同樣使用了建造者模式進行對象創建,主要用於解析對應的介面方法。

可以看到創建一個ServiceMethod對象需要依次創建CallAdapter請求調用轉換器,創建ResponseConverter響應數據轉換器,解析方法註解,方法參數註解,最後得到ServiceMethod對象。而CallAdapter和ResponseConverter的創建過程是通過查找Retrofit中的adapterFactories和converterFactories列表,根據方法的返回類型和參數類型查找是否有相應的Factory符合,如果有符合的Factory,即就可以得到最終的CallAdapter和ResponseConverter。

默認CallAdapter的轉換過程

默認Converter.Factory的列表中有一個ExecutorCallAdapterFactory,它的get方法返回一個CallAdapter對象,這個CallAdapter對象會將原始的OkHttpCall轉換為ExecutorCallbackCall,這個ExecutorCallbackCall就是我們介面方法中返回值定義的Call介面,它封裝了原始OkHttpCall用於網路請求和MainThreadExecutor用於響應數據時的線程切換。如

當call調用它的enqueue方法時,就會調用它內部的OkHttpCall的enqueue方法,進而執行執行Okhttp的enqueue方法開始非同步網路請求,響應返回時,用MainThreadExecutor對象將響應過程切換到主線程(默認Okhttp的響應方法是在其他線程中,MainThreadExecutor內部使用Handler將響應回調post到主線程處理)。

RxjavaCallAdapter的轉換過程

如果添加了Rxjava的支持,那麼在Converter.Factory列表中會有一個RxjavaCallAdapterFactory,它的get方法最終會返回一個SimpleCallAdapter對象(如果介面方法返回類型的泛型是我們定義的Bean類的話),這個SimpleCallAdapter對象會將原始的OkHttpCall轉換為一個Observable對象。有了這個Observable對象就可以很方便的作線程切換和後續的其他處理了。介面方法返回類型的泛型是Response或Result,那麼RxjavaCallAdapterFactory的get方法會返回ResponseCallAdapter或ResultCallAdapter。

然後它在CallOnSubscribe中觸發請求的調用。

這樣完成的RxJava式的轉換請求流程就走通了。

CallAdapter的轉換過程

那麼響應數據是在哪裡轉換成我們定義的類型的呢?它是在OkhttpCall中進行響應數據解析轉換的,不論是它的enqueue還是excute方法,響應結果都會交給parseResponse處理。

可以看到在enqueue或者excute方法執行得到響應數據後會到parseResponse將響應體數據轉換為指定類型,是調用當前serviceMethod的toResponse方法進行轉換,裡面會調用responseConverter進行convert轉換,如果我們在Retrofit配置時添加了GsonConverterFactory支持,那麼就會使用GsonConverterFactory中的GsonResponseBodyConverter進行類型轉換,而GsonResponseBodyConverter內部是使用gson進行類型轉換。

這樣響應數據類型的轉換就走通了。

總結

Retrofit源碼涉及了不少涉及模式,結構清晰,我想它最大的特點就是讓我們以最簡便的方式實現了我們的網路請求業務,同時高度的擴展性使能充分利用其它庫的優點為其服務。Okhttp為其處理底層網路請求(還包括緩存處理,日誌攔截等),RxJava為其提供更加廣闊的調用處理方式,Gson等其他解析為響應數據解析提供了保證等等。所以借用農夫三拳的話說,「我們不生產水 我們只是大自然的搬運工」,哈哈,Retrofit,一個安靜的集成管理者(美男子)。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 全球大搜羅 的精彩文章:

TAG:全球大搜羅 |