從 ServiceMethod角度來認識retrofit框架

對於Android開發者而言,retrofit可以說算是比較實用的網絡請求框架,而且是開源的。那麼,從請求執行的角度,以 interface 中我們定義的方法為起始,解讀 retrofit 的執行流程。目的是想讓我們對 retrofit 的執行流程有一個框架性的瞭解,同時也是為了面試的時候,可以跟面試官“有的聊”。

ServiceMethod是什麼?retrofit的核心思想是將 http 請求過程抽象成了一個對象 ServiceMethod。 這個對象的構造的時候,會通過 java 反射的方式傳入一個 method 對象,而這個對象就是我們在 interface 中定義的請求方法。通過對 method 對象 find usage ,我們可以發現,一共有兩處使用了這個 method 對象。

可以看到,裡面使用了 method 對象的兩個關鍵信息:註解和返回類型。而其中涉及的兩個方法則同時出現在了 ServiceMethod.build() 中。

public ServiceMethod build() {

callAdapter = createCallAdapter();

responseConverter = createResponseConverter();

}

通過 method 的 returnType 構造出 createCallAdapter 和 responseConverter,然後自動的完成從服務器的返回結果,到程序用的 model 類實例的轉換。通過 annotation 定義網絡請求相關的參數。annotation 的解析是一個簡單但繁瑣的工作,需要對每一個註解逐個判斷。因此我們把重點放在 callAdapter 和 responseConverter 的分析上。而我在閱讀相關代碼的過程中,發現其中的泛型部分對我們理解整個框架造成了很大的阻礙。因此,想理解 retrofit,必須要弄懂其各個泛型類的意義,不然看一看就自己把自己繞暈了。

從 ServiceMethod角度來認識retrofit框架

其中,getAlbums() 就是我們的 method 方法。根據這個 method 方法, 生成 ServiceMethod 對象,返回的結果是 serviceMethod.callAdapter.adapt(okHttpCall); 。而我們知道,我們在 interface 中定義的 getAlbums() 的返回類型恰好是 RadioCall,兩個類型就這麼對上了。

在radioCall.execute() 的內部,我們會把調用 delegates.execute() 來實際執行網絡請求。這個 delegates 的類型就是 retrofit.OkHttpCall。然後,發起請求,等待服務器返回結果,並對結果進行處理。尚學堂•百戰程序員陳老師指出,此時的結果還是 rawResponse,即都是 json 字符串,還不是可以直接使用的 java model 對象。這個時候,我們就需要 responseConverter 來幫我們進行轉換了。

正如我們上文所說,RadioCall 一般會把一個 okHttpCall 作為構造函數的參數,然後把實際請求委託給 okHttpCall,然後再 onResposne 回調中就能得到上面代碼中的 Response,將我們的類帶入,就是 Response。而這個,就是 execute() 的執行結果。然後我們就可以得到 Response 中的 model 對象了。

至此,retrofit 的請求執行流程就分析完畢。最後我們再從宏觀的角度,從面試的角度,來闡述一下整個執行過程。

首先我們通過我們 create 出來的 retrofit 實例來調用接口方法。所有的 interface 方法都會在 java 動態代理機制的作用下,調用一個匿名類 new InvocationHandler 中的 invoke。在 invoke 中,會根據我們想調用的方法 method 構造出一個 serviceMethod,然後調用 serviceMethod.callAdapter.adapt(okHttpCall) 作為返回結果。

構造 serviceMethod 的時候,會根據 interface 中 method 的的返回類型,構造出 converter 和 callAdapter。其中, converter 一般使用 gson converter。gson converter 可以自動將服務器返回的 json 數據轉化成 java 中的 model 類的實例。callAdapter 絕大多數的實現方式是在構造函數中接收一個 okHttpCall 實例,然後將 enqueue 和 execute 委託給這個 okHttpCall 實例來執行。okHttpCall 在獲取到服務器數據之後,會利用 serviceMethod.toResponse(body) 來對數據進行轉化。其中,轉化的時候便利用了 converter。數據轉化完成後,封裝成 Response ,傳遞給調用方。其中 R 就是我們的數據類。


分享到:


相關文章: