【一起學習開源框架】Retrofit相對於OKHttp,解決了什麼問題

語言: CN / TW / HK

theme: channing-cyan highlight: androidstudio


前言

在學習完Retrofit後,相信大家都會思考一個問題,OkHttp作為一個關於網路請求的第三方類庫,它已經是一種高內聚的,非常棒的關於網路請求方案具體的實現,而Retrofit的出現,它解決了OKhttp的哪些痛點呢?由於它本質網路請求還是依靠OKHttp來進行的,簡單來說,Retrofit就是對OKHttp的封裝,那麼它封裝的點是怎麼解決OKHttp這些不友好的地方呢?下面我們就一起來探討一下它們之前的聯絡吧

OKHttp流程概要

在討論OKHttpRetrofit的關係之前,我們先來回顧下,OKHttp構建的流程吧,大致有以下四個步驟

  1. 構建OkHttpClient例項
  2. 構建Request,具體網路請求引數(地址,請求頭等)
  3. 構建請求Call
  4. 伺服器返回資料response

下面以OKHttp非同步請求為例子: private fun asyRequest() {        //1.構建okhttpClient例項        val client = OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build()        //2.構建Request,網路請求引數        val request = Request.Builder().url("http://www.baidu.com")           .get().build()        //3.構建請求call        val call = client.newCall(request)        //請求資料返回,手動切換請求介面卡,手動切換執行緒        call.enqueue(object : Callback {            override fun onFailure(call: Call, e: IOException) {                println(e.message)           } ​            override fun onResponse(call: Call, response: Response) {                println(response.body().toString())           } ​       })   }

具體的結果response需要自己去解析,都是由使用者自己去實現的,而OKHttp主要工作就是用來網路請求,也就是一種高內聚的,非常棒的關於網路請求方案具體的實現

okhttp流程.png

Retrofit相對於OKHttp所解決的問題

Retrofit的出現是為了更好的方便我們APP應用層來使用網路請求,解決OKHttp使用中存在的一些問題

OKHttp存在的缺陷

我們在使用OKHttp過程當中會存在以下缺陷

  • 客戶端網路請求的介面配置比較繁瑣,尤其是在需要配置複雜請求body,請求頭,引數的時候
  • 資料解析過程中需要客戶端手動拿到responseBody進行解析,而且還不能複用
  • 無法適配自動進行執行緒的切換
  • 萬一我們存在巢狀網路請求就會陷入"回撥陷阱"

所以為了解決以上問題,Retrofit就出現了,所以它並不是一個網路請求框架,準確來說,它就是一個RESTful風格的Http網路請求框架的封裝,本質由OKHttp完成,而它僅僅負責網路請求介面的封裝;

Retrofit出生開始就已經決定了它只是為了方便應用層來使用網路請求

  1. App應用層通過Retrofit去請求網路,實際上是使用Retrofit介面層封裝請求引數,HeaderUrl等資訊,這些不再需要我們手動去配置了,之後就是OKHttp來完成後續的操作
  2. 等到伺服器返回資料之後,OKHttp將原始的資料結果交給Retrofit,然後它更具使用者的需求對結果進行解析,這樣基本解決了OKHttp中的無法自動進行資料解析和複用的問題了
  3. 總的來說,Retrofit優化了網路請求的使用,分別在建立網路請求的時候以及網路請求資料返回解析的時候,這樣一來,圖示就很明顯了,如何去更好的建立Okhttp的網路請求Okhttp返回資料之後如何更好的去解析Retrofit基本上就解決了這兩個問題

retrofit封裝的點

我們已經知道Retrofit是為了解決OKHttp存在的問題而引申出來的,那麼Retrofit針對這些問題時如何進行封裝的呢?它封裝的點是怎麼樣的,可以通過下面這張圖直觀感受到

  • Okhttp建立的是OKHttpClient,然而retrofit建立的是Retrofit例項
  • 構建藍色的Request的方案,Retrofit是通過註解來進行適配
  • 配置Call的過程中,Retrofit是利用Adapter適配的OKHttpCall,為Call的適配提供了多樣性,那麼Retrofit可以支援Rxjava,這樣一來就可以解決上面所提到的網路請求巢狀問題
  • 相對OKHttp,Retrofit會對responseBody進行自動的GSON解析,提供了可複用,易拓展的資料解析方案
  • 相對OKHttp,Retrofit會自動的完成執行緒的切換

RetrofitOKHttp的關係闡述

通過上面我們已經知道,Retrofit設計的任務主要就發生在OKHttp網路的請求前和請求後,下面我們就來看下請求前後Retrofit做了什麼工作,如圖所示

  1. 請求前主要做了兩件事情: 統一配置網路請求頭和一致適配請求Request,我們知道OKHttp實現的是Http協議,那麼就有一定的規則,請求方法就只有八種(GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,HTTP),既然都是符合Http協議的規則,那麼就可以使用統一的規則來適配網路請求,這些在Retrofit裡就是通過註解的形式,按照一定的策略來調配, 所以我們就把註解的解析過程看成一致適配請求Request
  2. 請求後也做了兩件事情,就是將執行緒自動切換,資料自動適配成我們需要的java物件並且展示在UI執行緒

總體來說,我們知道了Retrofit在逐力解決上述這些問題,這也就是Retrofit的核心是用動態代理的原因了,因為請求前需要適配Request進行網路請求,而這個網路請求是由OKHttp這個委託者代理完成的,換句話說,Retrofit其實本身並不具備網路請求功能,它只是被OKHttp委託Retrofit對外進行網路請求,而Retrofit只是個代理,只是在網路請求前進行請求統一配置,請求之後進行資料處理,真正的網路請求依舊是OKHttp進行的;所以當問到Retrofit是如何進行網路請求的?回答只需要和OKHttp的一樣就可以了