【一起學習開源框架】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("https://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的一樣就可以了