android原始碼宇宙-Retrofit
Retrofit使用
Retrofit原始碼
主流程
- 原始碼檢視入口
- Retrofit動態代理監聽
- validateServiceInterface如何進行合法性校驗和方法初始化
- 接著第2步和第3步看loadServiceMethod方法
這裡的ConcurrentHashMap就是一個ConcurrentHashMap
- 看看ServiceMethod.parseAnnotations是如何建立ServiceMethod的
- HttpServiceMethod.paresAnnotations方法,獲取ServiceMethod方法
- 兩種kotlin的HttpServiceMethod(SuspendForResponse、SuspendForBody)的實現的內部原理
- HttpServiceMethod的執行
上面的第6/7步生成了一個ServiceMethod,ServiceMethod就是Retrofit橋接okhttp的關鍵程式碼。
在第2步中loadServiceMethod後會使用invoke方法執行請求,如下:
然後我們發現invoke是ServiceMethod中的方法,沒有被子類實現。它內部實現如下:
也就是說invoke方法中會呼叫adapt方法,而這個adapt方法是需要子類實現的。所以我們去看adapt方法就可以了。
- 主流程結束
Retrofit是如何代理Okhttp的
- 首先使用一個OkHttpCall內部持有一個okhttp3.Call物件
2. OkhttpCall內部有executed方法和enqueue方法,內部會呼叫rawCall的相關方法實現代理okhttp3.Call
例如1,executed方法
而enqueue方法,內部會使用okhttp3.AsyncCall.enqueue進行非同步請求,在相關的回撥方法中響應回撥資料。
這裡的call的實際型別是OkHttpCall
CallAdapter.Factory是如何工作的
- 設定CallAdapterFactory的方法
- Retrofit是會有預設的CallAdapter.Factory 的,建立預設CallAdapter.Factory位置如下
3. HttpServiceMethod.parseAnnotations方法中獲取使用CallAdapter.Factory
- 將callAdapter傳入ServiceMethod中
- 我們分別看看CallAdapted和SuspendForResponse兩種的實現
- CallAdapted
- SuspendForResponse
- 結束
Converter.Factory是如何工作的
- 構建請求的時候可以設定解析工廠類
- 然後會把解析工廠新增到Retrofit中
- 我們是如何使用converter工廠的
- 當執行HttpServiceMethod的invoke方法的時候會構建OkhttpCall
- 使用Converter解析返回結果
- 返回最終結果
預設的請求Converter
請求的預設Converter很簡單,就一個,呼叫它的convert方法的時候,會直接把原裝的RequestBody返回。
預設的響應Converter
響應的Converter有多種,如下圖
總結
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
上一段中返回了一個OkHttpCall型別,然後我們會呼叫executed或enqueue同步或非同步獲取請求結果。例如呼叫enqueue的時候,OkHttpCall.enqueue內部會呼叫okhttp3.Call.enqueue執行請求,請求成功後會使用回撥介面來回調資料(需要強調的是在OkHttpCall的enqueue和execute方法中都會呼叫parseResponse方法對響應進行處理,在parseResponse方法中會呼叫我們的converter對結果進行處理,然後包裝成一個新的Response型別,新的Response中的body就是我們期望的返回型別。預設的Response.body是ResponseBody型別,如果使用GsonConverterFactory進行處理,Response.body型別就是我們期望的實體類型別)。