android原始碼宇宙-Retrofit

語言: CN / TW / HK

Retrofit使用

image.png

Retrofit原始碼

主流程

  1. 原始碼檢視入口

image.png

  1. Retrofit動態代理監聽

image.png

  1. validateServiceInterface如何進行合法性校驗和方法初始化

image.png

  1. 接著第2步和第3步看loadServiceMethod方法

    這裡的ConcurrentHashMap就是一個ConcurrentHashMap

image.png

  1. 看看ServiceMethod.parseAnnotations是如何建立ServiceMethod的

image.png

  1. HttpServiceMethod.paresAnnotations方法,獲取ServiceMethod方法

image.png
image.png
image.png

  1. 兩種kotlin的HttpServiceMethod(SuspendForResponse、SuspendForBody)的實現的內部原理

image.png

  1. HttpServiceMethod的執行

上面的第6/7步生成了一個ServiceMethod,ServiceMethod就是Retrofit橋接okhttp的關鍵程式碼。
在第2步中loadServiceMethod後會使用invoke方法執行請求,如下:
image.png
然後我們發現invoke是ServiceMethod中的方法,沒有被子類實現。它內部實現如下:
image.png
也就是說invoke方法中會呼叫adapt方法,而這個adapt方法是需要子類實現的。所以我們去看adapt方法就可以了。

  1. 主流程結束

Retrofit是如何代理Okhttp的

  1. 首先使用一個OkHttpCall內部持有一個okhttp3.Call物件

image.png
2. OkhttpCall內部有executed方法和enqueue方法,內部會呼叫rawCall的相關方法實現代理okhttp3.Call
例如1,executed方法
image.png
而enqueue方法,內部會使用okhttp3.AsyncCall.enqueue進行非同步請求,在相關的回撥方法中響應回撥資料。
這裡的call的實際型別是OkHttpCall
image.png

CallAdapter.Factory是如何工作的

  1. 設定CallAdapterFactory的方法

image.png

  1. Retrofit是會有預設的CallAdapter.Factory 的,建立預設CallAdapter.Factory位置如下

image.png
3. HttpServiceMethod.parseAnnotations方法中獲取使用CallAdapter.Factory
image.png

  1. 將callAdapter傳入ServiceMethod中

image.png

  1. 我們分別看看CallAdapted和SuspendForResponse兩種的實現
  2. CallAdapted

image.png

  • SuspendForResponse

image.png

  1. 結束

Converter.Factory是如何工作的

  1. 構建請求的時候可以設定解析工廠類

image.png

  1. 然後會把解析工廠新增到Retrofit中

image.png

  1. 我們是如何使用converter工廠的

image.png

  1. 當執行HttpServiceMethod的invoke方法的時候會構建OkhttpCall

image.png

  1. 使用Converter解析返回結果

image.png

  1. 返回最終結果

image.png
image.png

預設的請求Converter

請求的預設Converter很簡單,就一個,呼叫它的convert方法的時候,會直接把原裝的RequestBody返回。
image.png

預設的響應Converter

響應的Converter有多種,如下圖
image.png

總結

Retrofit在呼叫Retrofit.create建立Service介面例項的時候,會建立一個動態代理的監聽。每次我們呼叫Service方法的時候就會回撥動態代理的invoke方法。然後在動態代理的回撥裡面會經過多重邏輯處理後,呼叫loadServiceMethod建立ServiceMethod例項,ServiceMethod是一個抽象類,他有三個預設的實現類,分別是CallAdapted、SuspendForResponse、SuspendForBody,其中後兩個用在suspend方法協程中的。
loadServiceMethod返回ServiceMethod後,會呼叫ServiceMethod的invoke方法,invoke方法是在父類ServiceMethod中的(需要強調的是,我們後面提到的OkHttpCall也是在這個方法中建立的),invoke方法中會呼叫adapt方法,adapt方法每個子類中都會實現。子類中會呼叫callAdapter.adapt獲取響應Response,然後不同的ServiceMethod實現會執行自己的邏輯對Response處理,最終會返回一個Call物件,預設會返回retrofit2.OkHttpCall型別。
上一段中返回了一個OkHttpCall型別,然後我們會呼叫executed或enqueue同步或非同步獲取請求結果。例如呼叫enqueue的時候,OkHttpCall.enqueue內部會呼叫okhttp3.Call.enqueue執行請求,請求成功後會使用回撥介面來回調資料(需要強調的是在OkHttpCall的enqueue和execute方法中都會呼叫parseResponse方法對響應進行處理,在parseResponse方法中會呼叫我們的converter對結果進行處理,然後包裝成一個新的Response型別,新的Response中的body就是我們期望的返回型別。預設的Response.body是ResponseBody型別,如果使用GsonConverterFactory進行處理,Response.body型別就是我們期望的實體類型別)。