臨到面試不懂OkHttp與Retrofit?這一次愛奇藝大佬帶你深度分析OkHttp源碼與Retrofit封裝,全面瞭解!

我們項目當中的每個app都需要用到網絡和服務器進行交互,在Android項目開發中使用HTTP協議完成通信的話,基本上都要用到OkHttp或者Retrofit。

OkHttp和Retrofit是目前應用最爲廣泛的網絡組件,面試幾乎必問。

面試時問到比較開放性的問題,比如你覺得Retrofit有什麼缺點?如何優化?

像這種問題其實沒有標準答案,但是我們一定要對Retrofit的原理熟悉,並且結合自己的思想,說出自己的理解,能夠解釋清楚,邏輯是..順暢的就沒問題。

但是很多同學害怕這種類型的問題,因爲大家應該都能夠感受到自己更習慣按部就班的按照人家制定好的計劃來學習,缺乏自己的思想。

面試之前也是瘋狂去刷題,所以問到有標準答案的問題大家能去死記硬背,反而沒那麼害怕。

而如果在面試時,或者在開發中遇到沒有“標準答案”的問題,那隻能懵逼了。

OkHttp

OkHttp是一個高效的HTTP客戶端,是目前Android使用最廣泛的網絡框架。它的橫空出世,讓其他的網絡請求框架都變得黯然失色。

優點:

  • 支持Http1、Http2、Quic以及WebSocket;
  • 連接池複用底層TCP(Socket),減少請求延時;
  • 無縫的支持GZIP減少數據流量;
  • 緩存響應數據減少重複的網絡請求;
  • 請求失敗自動重試主機的其他ip,自動重定向;

Retrofit

準確來說,Retrofit 是一個 RESTful 的 HTTP 網絡請求框架的封裝。

原因:網絡請求的工作本質上是 OkHttp 完成,而 Retrofit 僅負責網絡請求接口的封裝。

App應用程序通過Retrofit請求網絡,實際上是使用Retrofit接口層封裝請求參數、Header、Url 等信息,之後由 OkHttp 完成後續的請求操作。

在服務端返回數據之後,OkHttp 將原始的結果交給 Retrofit,Retrofit根據用戶的需求對結果進行解析。

所以,網絡請求的本質仍舊是OkHttp完成的,retrofit只是幫使用者來進行工作簡化的,比如配置網絡,處理數據等工作,提高這一系列操作的複用性。這也就是網上流行的一個不太準確的總結:OkHttp是瑞士軍刀,retrofit則是將瑞士軍刀包裝成了一個非常好用的指甲鉗。

Retrofit 對Okhttp做了什麼

Retrofit並沒有改變網絡請求的本質,也無需改變,因爲OkHttp已經足夠強大,Retrofit的封裝可以說是很強大,裏面涉及到一堆的設計模式,可以通過註解直接配置請求,可以使用不同的http客戶端,雖然默認是用http,可以使用不同Json Converter 來序列化數據,同時提供對RxJava的支持,使用Retrofit + OkHttp + RxJava可以說是目前比較潮的一套框架,但是需要有比較高的門檻。

下面我們來對比一下OkHttp網絡請求和 retrofit網絡請求的區別。

1. Okhttp請求總結

大家先看下面okhttp請求的樣例代碼:

private void testOkHttp() throws IOException {
      //Step1
      final OkHttpClient client = new OkHttpClient();
      //Step2
      final Request request = new Request.Builder()
          .url("https://www.google.com.hk").build();
      //Step3
      Call call = client.newCall(request);
      //step4 發送網絡請求,獲取數據,進行後續處理
      call.enqueue(new Callback() {
          @Override
          public void onFailure(Call call, IOException e) {

          }

          @Override
          public void onResponse(Call call, Response response) throws IOException {
                  Log.i(TAG,response.toString());
                  Log.i(TAG,response.body().string());
          }
      });
  }

解析一下上面的代碼:

Step1:創建HttpClient對象,也就是構建一個網絡類型的實例,一般會將所有的網絡請求使用同一個單例對象。

Step2:構建Request,也就是構建一個具體的網絡請求對象,具體的請求url,請求頭,請求體等等。

Step3:構建請求Call,也就是將具體的網絡請求與執行請求的實體進行綁定,形成一個具體的正式的可執行實體。

Step4:後面就進行網絡請求了,然後處理網絡請求的數據了。

總結一下:

OKhttp的意義:OkHttp是基於Http協議封裝的一套請求客戶端,雖然它也可以開線程,但根本上它更偏向真正的請求,跟HttpClient,HttpUrlConnection的職責是一樣的。

OkHttp的職責:OkHttp主要負責socket部分的優化,比如多路複用,buffer緩存,數據壓縮等等。

如果你想了解具體的OkHttp細節講解,可以在文末尋找答案。

OkHttp給用戶留下的問題

1)用戶網絡請求的接口配置繁瑣,尤其是需要配置請求body,請求頭,參數的時候;

2)數據解析過程需要用戶手動拿到responsbody進行解析,不能複用;

3)無法適配自動進行線程的切換。

那麼這幾個問題誰來解決?對,retrofit!

2.Retrofit請求總結

Retrofit 進行網絡請求的流程樣板代碼:

//step1
Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.wanandroid.com/")
                .addConverterFactory(GsonConverterFactory.create(new Gson()))
                .build();
//step2
ISharedListService sharedListService =  retrofit.create(ISharedListService.class);
//step3
Call<SharedListBean> sharedListCall = sharedListService.getSharedList(2,1);
//step4
sharedListCall.enqueue(new Callback<SharedListBean>() {
     @Override
     public void onResponse(Call<SharedListBean> call, Response<SharedListBean> response{
         if (response.isSuccessful()) {
                 System.out.println(response.body().toString());
             }
         }

        @Override
        public void onFailure(Call<SharedListBean> call, Throwable t) {
           t.printStackTrace();
        }
});

Step1: 創建retrofit對象,構建一個網絡請求的載體對象,和OkHttp構建OkhttpClient對象有一樣的意義,只不過retrofit在build的時候有非常多的初始化內容,這些內容可以爲後面網絡請求提供準備,如準備 現成轉換Executor,Gson convert,RxJavaCallAdapter。

Step2:Retrofit的精髓,爲統一配置網絡請求完成動態代理的設置。

Step3:構建具體網絡請求對象Request(service),在這個階段要完成的任務:

1)將接口中的註解翻譯成對應的參數;
2)確定網絡請求接口的返回值response類型以及對應的轉換器;
3)將Okhttp的Request封裝成爲Retrofit的 OKhttpCall。

總結來說,就是根據請求service 的Interface來封裝Okhttp請求Request。

Step4:後面就進行網絡請求了,然後處理網絡請求的數據了

總結一下

Retrofit主要負責應用層面的封裝,就是說主要面向開發者,方便使用,比如請求參數,響應數據的處理,錯誤處理等等。

Retrofit封裝了具體的請求,線程切換以及數據轉換。

網上一般都推薦RxJava+Retrofit+OkHttp框架,Retrofit負責請求的數據和請求的結果,使用接口的方式呈現,OkHttp負責請求的過程,RxJava負責異步,各種線程之間的切換,用起來非常便利。

小結:

通過下圖,讓我們來總結一下,retrofit是如何來封裝okhttp請求的。

大體的網絡流程是一致的,畢竟都是通過OkHttp進行網絡請求。

主要的步驟都是:

創建網絡請求實體client -> 構建真正的網絡請求 -> 將網絡請求方案與真正的網絡請求實體結合構成一個請求Call -> 執行網絡請求 -> 處理返回數據 -> 處理Android 平臺的線程問題。

在上圖中,我們看到的對比最大的區別是什麼?

1. OkHttp創建的是OkhttpClient,然而retrofit創建的是Retrofit實例
2. 構建藍色的Requet的方案,retrofit是通過註解來進行的適配
3. 配置Call的過程中,retrofit是利用Adapter適配的Okhttp的Call
4. 相對okhttp,retrofit會對responseBody進行自動Gson解析
5. 相對okhttp,retrofit會自動的完成線程的切換。

具體的實現細節、設計模式、實現方案思路,我特地整理了一份1042頁的《設計思想解讀開源框架》給大家,帶你深度分析OkHttp源碼與Retrofit封裝,梳理Retrofit的原理。

設計思想解讀開源框架

第一章、熱修復設計

第一節、AOT/JIT & dexopt 與 dex2oat
第二節、熱修復設計之 CLASS_ISPREVERIFIED 問題
第三節、熱修復設計之熱修復原理
第四節、Tinker 的集成與使用(自動補丁包生成)

第二章、插件化框架設計

第一節、Class 文件與 Dex 文件的結構解讀
第二節、Android 資源加載機制詳解
第三節、四大組件調用原理
第四節、so 文件加載機制
第五節、Android 系統服務實現原理

第三章、組件化框架設計

第一節、阿里巴巴開源路由框——ARouter 原理分析
第二節、APT 編譯時期自動生成代碼&動態類加載
第三節、Java SPI 機制
第四節、AOP&IOC
第五節、手寫組件化架構

第四章、圖片加載框架

第一節、圖片加載框架選型
第二節、Glide 原理分析
第三節、手寫圖片加載框架實戰

今天的重點來了:

第五章、網絡訪問框架設計

第一節、網絡通信必備基礎
第二節、OkHttp 源碼解讀
第三節、Retrofit 源碼解析

第六章、RXJava 響應式編程框架設計

第一節、鏈式調用
第二節、擴展的觀察者模式
第三節、事件變換設計
第四節、Scheduler 線程控制

第七章、IOC 架構設計

第一節、依賴注入與控制反轉
第二節、ButterKnife 原理
第三節、Dagger 架構設計核心解密

第八章、Android 架構組件 Jetpack

第一節、LiveData 原理
第二節、Navigation 如何解決 tabLayout 問題
第三節、ViewModel如何感知View生命週期及內核原理
第四節、Room 架構方式方法
第五節、dataBinding 爲什麼能夠支持 MVVM
第六節、WorkManager 內核揭祕
第七節、Lifecycles 生命週期

OkHttp與Retrofit相關的面試題

來看看大廠面試中關於OkHttp與Retrofit面試官們都喜歡問些什麼問題呢?

  • 你是怎麼搭建Android應用框架的?
  • 責任鏈模式
  • interceptors和networkInterceptors的區別?
  • 設計模式和封層解耦的理念
  • 動態代理
  • .........

面試答案詳細解析:

最後爲了幫助大家深刻理解OkHttp與Retrofit相關知識點的原理以及面試相關知識,這裏還爲大家整理了Android開發相關源碼精編解析

深入解析 Retrofit源碼

深入解析OkHttp 源碼

最後爲了幫助大家深刻理解Android相關知識點的原理以及面試相關知識,這裏放上我搜集整理的2019-2020BAT 面試真題解析,我把大廠面試中常被問到的技術點整理成了PDF,包知識脈絡 + 諸多細節。

節省大家在網上搜索資料的時間來學習,也可以分享給身邊好友一起學習。

不用多說,相信大家都有一個共識:無論什麼行業,最牛逼的人肯定是站在金字塔端的人。所以,想做一個牛逼的程序員,那麼就要讓自己站的更高,成爲技術大牛並不是一朝一夕的事情,需要時間的沉澱和技術的積累。加油,共勉~

以上內容均免費分享給大家,需要完整版的朋友,點這裏可以看到全部內容。或者關注主頁掃描加 微信 獲取。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章