Retrofit源碼初探

什么是Retrofit2

Retrofit2 可以說是目前最流行的類型安全網(wǎng)絡庫,是Square公司的一個開源項目诗芜,通過注解來創(chuàng)建restful API接口韧献。目前2.0版本已經(jīng)穩(wěn)定竣贪,下文如無特殊說明,均指2.0版本卡者。
Retrofit2使用步驟
Retrofit2的使用很簡單蒿囤,主要分為以下幾個步驟:
創(chuàng)建Interface接口,通過注解標識客戶端與后臺約定的API接口

public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}

創(chuàng)建Retrofit實例崇决,生成Interface的實現(xiàn)類(動態(tài)代理實現(xiàn)對象)

Retrofit retrofit = new Retrofit.Builder().baseUrl("[https://api.github.com](https://api.github.com/)").build();
GitHubService service = retrofit.create(GitHubService.class);

調用上面創(chuàng)建的實現(xiàn)類中的API請求方法材诽,取得Call對象

Call<List<Repo>> repos = service.listRepos("octocat");

根據(jù)調用場景異步或同步底挫,執(zhí)行call對象的同步或異步執(zhí)行方法,異步方法需要傳入Callback回調參數(shù)
異步:call.enqueue(Callback callback)
同步:call.execute()

Retrofit2內部原理

根據(jù)上面Retrofit2使用步驟脸侥,我們逐步來探究Retrofit內部的奧秘
第一步?jīng)]啥好說的建邓,就是根據(jù)跟服務器的接口協(xié)議文檔寫注解接口。

根據(jù)接口創(chuàng)建相關執(zhí)行代理對象睁枕。從源代碼可以看到此處使用了JAVA中的動態(tài)代理技術官边,類似于方法hook,調用接口中的任何方法都會事先調用proxy中的鉤子方法外遇。
動態(tài)代理

這里的鉤子方法為

loadMethodHandler(method).invoke(args)

我們一步步跟下去注簿,接著看loadMethodHandler方法


loadMethodHandler方法

loadMethodHandler方法就是根據(jù)method返回相應的methodHandler。MethodHandler顧名思義為方法處理器跳仿,method與MethodHandler一一對應的關系是采用map實現(xiàn)的诡渴。一個method對應一個MethodHandler,如果當前method對應handler不存在則會創(chuàng)建一個然后再put到map里面菲语。通過method獲取對應的handler后妄辩,調用handler的invoke()方法。

handler的invoke方法

我們再往里面分析山上,可以看到invoke方法使用CallAdapter進行Call<R>的轉換眼耀。Call轉換工作是通過CallAdapter call適配器的adapt方法進行的。

  • CallAdapter是什么佩憾?顧名思義就是Call的適配器哮伟,作用就是創(chuàng)建/轉換Call對象,把Call轉換成預期的格式妄帘。CallAdatper創(chuàng)建是通過CallAdapter.factory工廠類進行的澈吨,本身只有一個轉換方法adapt()。創(chuàng)建CallAdatper Factory需要實現(xiàn)Factory接口寄摆,接口只包含一個方法CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit); 通過傳入的returnType參數(shù)來返回相應的CallAdapter。

interface Factory {
CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit);}

DefaultCallAdapter為Retrofit2自帶默認Call轉換器修赞,用來生成OKHTTP的call請求調用婶恼。Retrofit內部維護著一個calladapterFactory列表。Retrofit會依次遍歷adapterFactory list列表來查詢并返回能夠處理對應returntype的calladapter柏副,如果一個都獲取不到勾邦,則拋出illegalArgument異常。Retrofit內置2種callAdapter割择,都只能處理返回類型為Call的調用眷篇。兩者唯一區(qū)別是Call的回調是否通過指定的Executor執(zhí)行。

  • 異步/同步發(fā)起請求荔泳。請求最終生成的還是okhttp raw call蕉饼,然后再分別進行異步/同步調用虐杯。okhttp raw call的生成是通過RequestFactory來完成的。

RequestFactory生成Request方法

  • 返回請求的解析昧港。服務器返回的數(shù)據(jù)格式一般為JSON/XML擎椰,采用相應的解析器ResponseConverter轉換成Class對象。ResonseConverter實現(xiàn)Converter接口创肥,Converter接口只有一個T convert(F value)方法和Factory工廠內部類达舒。用戶自定義Converter需實現(xiàn)Converter接口。Retrofit內部維護著一個ResonseConvert列表叹侄,代表retrofit解析結果的能力巩搏。Retrofit解析的時候依次從列表中取出converter嘗試做轉換,轉換成功則返回轉換Class對象趾代,如果轉換失敗贯底,繼續(xù)選取列表中下一個Converter直到最后失敗拋出IllegalArgumentException(Could not locate ResponseBody converter for **)異常。

系統(tǒng)處理Response解析稽坤,查找匹配converter方法

總結

Retrofit源代碼初步解讀就到此結束丈甸,在分析的過程中深刻感覺頂尖高手寫的代碼是多么的巧妙,需向大牛們多多學習尿褪。Retrofit2庫主要涉及到的知識點:泛型睦擂,注解。運用的設計模式:工廠模式杖玲,適配器模式顿仇,單例模式,代理模式摆马。通過適配器模式實現(xiàn)了Retrofit的插件化臼闻。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市囤采,隨后出現(xiàn)的幾起案子述呐,更是在濱河造成了極大的恐慌,老刑警劉巖蕉毯,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乓搬,死亡現(xiàn)場離奇詭異,居然都是意外死亡代虾,警方通過查閱死者的電腦和手機进肯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棉磨,“玉大人江掩,你說我怎么就攤上這事。” “怎么了环形?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵策泣,是天一觀的道長。 經(jīng)常有香客問我斟赚,道長着降,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任拗军,我火速辦了婚禮任洞,結果婚禮上,老公的妹妹穿的比我還像新娘发侵。我一直安慰自己交掏,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布刃鳄。 她就那樣靜靜地躺著盅弛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叔锐。 梳的紋絲不亂的頭發(fā)上挪鹏,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音愉烙,去河邊找鬼讨盒。 笑死,一個胖子當著我的面吹牛步责,可吹牛的內容都是我干的返顺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蔓肯,長吁一口氣:“原來是場噩夢啊……” “哼遂鹊!你這毒婦竟也來了?” 一聲冷哼從身側響起蔗包,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤秉扑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后调限,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邻储,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年旧噪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脓匿。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡淘钟,死狀恐怖,靈堂內的尸體忽然破棺而出陪毡,到底是詐尸還是另有隱情米母,我是刑警寧澤勾扭,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站铁瞒,受9級特大地震影響妙色,放射性物質發(fā)生泄漏。R本人自食惡果不足惜慧耍,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一身辨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芍碧,春花似錦煌珊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至踪危,卻和暖如春蔬浙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贞远。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工畴博, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人兴革。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓绎晃,卻偏偏與公主長得像,于是被迫代替她去往敵國和親杂曲。 傳聞我的和親對象是個殘疾皇子庶艾,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內容

  • 簡介 剛接觸Retrofit的時候,就寫了一篇簡單的使用介紹:Retrofit 2.0基本使用方法,算是對Retr...
    Whyn閱讀 2,844評論 4 24
  • Retrofit是squareup公司的開源力作,和同屬squareup公司開源的OkHttp棚饵,一個負責網(wǎng)絡調度煤裙,...
    藍灰_q閱讀 41,481評論 23 281
  • 最近非常流行 Retrofit+RxJava+OkHttp 這一整套的網(wǎng)絡請求和異步操作的開源框架,從 Jake ...
    慌不要慌閱讀 1,974評論 1 7
  • Retrofit這個開源庫出來也有一定年頭了噪漾,記得之前還是在V1.0的版本的時候硼砰,之前在三月份也寫過一個Retro...
    lovejjfg閱讀 1,448評論 0 5
  • 慢慢地長大了题翰,昨日還陪伴在左右的人,一回頭,竟早已不見了蹤影豹障。小時候的玩伴馬上就要嫁為人婦冯事,小學同學抑或兒女成雙,...
    silencegyx閱讀 290評論 0 0