retrofit整體代碼量不是很大,但是涉及到的知識點(diǎn)還是很多的,也是一款很好的解耦封裝框架,在其中是能夠?qū)W習(xí)到很多東西的,當(dāng)前鑒于時(shí)間原因先重點(diǎn)分析retrofit的流程邏輯實(shí)現(xiàn),里面的涉及到的知識點(diǎn)后續(xù)會(huì)有文章分析學(xué)習(xí)(水平有限,有些可能分析不到位,歡迎小伙伴指正討論,噴就沒必要了吧)。
-
從組建者模式淺談retrofit對象的組建
retrofit實(shí)例創(chuàng)建
- 如上代碼所示,retrofit很明顯是build(組建者模式),組建者模式特性:
????* builder模式通常對象內(nèi)部存在builder組建類,通常是static修飾,可以通過對象直接訪問,還可能設(shè)置成為final,不能被繼承修改。
????* builder內(nèi)部屬性api通常是鏈性的,可以鏈?zhǔn)秸{(diào)用
????* builder除了內(nèi)置屬性設(shè)置外,比較特殊的就是構(gòu)造方法和組建方法build(),retrofit我們也是重點(diǎn)分析這兩個(gè)api。 -
構(gòu)造方法Builder():
retrofit builder api
承接上文????* 如圖所示:下面的builder構(gòu)造方法接受platform作為參數(shù),而上面而是傳入的platform.get(),繼續(xù)向下跟Platform這個(gè)對象做什么用:
????* get返回的靜態(tài)變量PLATFORM,找到改變量的初始化方法findPlatform();跟進(jìn)去方法如下:Platform的get api
????* api方法代碼很簡單也不麻煩就是校驗(yàn)了是否是Android平臺(tái)若Android平臺(tái)返回了Android對象,非Android平臺(tái)返回了platform示例,我們當(dāng)前分析Android,重點(diǎn)看一下Android對象的實(shí)現(xiàn),即:findPlatform()
Android對象????* 通過Android handler實(shí)現(xiàn)的默認(rèn)回調(diào)線程是Android的ui線程。在Android平臺(tái)retrofit會(huì)將響應(yīng)的數(shù)據(jù)自動(dòng)切回到ui線程,所以使用rxjava+okhttp+retrofit要切實(shí)分析其接口請求和接口響應(yīng)都在那一個(gè)線程中,不然極其容易出問題,接口請求通常要么是rxjava(外部線程處理)或者okhttp異步處理,retrofit是不處理接口請求的線程邏輯,但是retrofit是處理了接口返回的線程(無論請求什么線程都會(huì)將響應(yīng)切回UI線程)。
- builder對象通過一系列的set api對其屬性進(jìn)行設(shè)置賦值,具體api在上面圖片介紹上都添加了注釋,不再一一解釋。
-
builder即時(shí)沒有設(shè)置其屬性,在對象組建方法build中每一個(gè)屬性也有其對應(yīng)的默認(rèn)賦值,build方法如下:
build方法實(shí)現(xiàn)????* 簡要分析api的實(shí)現(xiàn),外面用戶沒有設(shè)置的情形下,判空后將callFactory指向了okhttpClient,后續(xù)callAdapter和CovertAdapter都將默認(rèn)的實(shí)例類添加到了對應(yīng)的list列表中去。
- 由上面的步驟我們就獲取到了retrofit的示例對象,將設(shè)置其對應(yīng)的上下文環(huán)境,默認(rèn)的call示例和默認(rèn)的covert實(shí)例。
-
通過反射,注解,抽象代理等技術(shù)retrofit創(chuàng)建聲明的接口的一個(gè)實(shí)例對象并實(shí)現(xiàn)內(nèi)部的api方法,根據(jù)方法的注解將其封裝到okhttpcall對象。
retrofit創(chuàng)建抽象接口對象
- 這一塊是retrofit的核心代碼,也是難點(diǎn)最多的代碼,涉及到j(luò)ava的反射,注解等,設(shè)計(jì)模式的抽象代理,水平有限這一塊只能說一下個(gè)人的簡單理解,更多的是流程邏輯的實(shí)現(xiàn),具體細(xì)節(jié)實(shí)現(xiàn)分析后續(xù)單開文章消化解析。
-
由上面的可知入口方法是create,下面是create的代碼實(shí)現(xiàn):create方法實(shí)現(xiàn)
- api首先對于創(chuàng)建的類進(jìn)行校驗(yàn)處理,即validateServiceInterface的實(shí)現(xiàn):????* 如圖所示對于api的重點(diǎn)邏輯已做標(biāo)識處理,不再詳述,getTypeParametersvalidateServiceInterface
-
通過抽象代理創(chuàng)建接口的實(shí)例對象及其對應(yīng)方法的實(shí)現(xiàn),這一塊當(dāng)前還不熟暫不詳細(xì)分析,這段代碼流程邏輯是先反射實(shí)現(xiàn)聲明的方法,然后校驗(yàn)方法是否是默認(rèn)方法,java對于默認(rèn)方法的理解是有具體的實(shí)現(xiàn)的方法就是默認(rèn)方法,接口中一般聲明的都不是默認(rèn)方法,所以第三個(gè)圈中不會(huì)處理,會(huì)直接走到loadService方法,這方法上面校驗(yàn)接口類的時(shí)候又出現(xiàn),主要處理了方法的注解解析。下面跟著去看這個(gè)方法的實(shí)現(xiàn):
loadService - 方法使用容器及類單例實(shí)現(xiàn)了方法的唯一,這個(gè)后續(xù)有篇文章分析使用容器實(shí)現(xiàn)多方法或者多對象的唯一性實(shí)現(xiàn)
-
拋去上面描述的,方法的核心實(shí)現(xiàn)集中在ServiceMethod.parseAnnotations(this, method),繼續(xù)向下跟:
ServiceMethod - 這個(gè)api方法比較簡單明了,主要做個(gè)兩步:
????* 將接口中聲明的注解http協(xié)議,header協(xié)議,接口參數(shù)等解析并封裝到對應(yīng)的RequestFactory中去。
????* 將上面的requestfactory和method和retrofit串聯(lián)起來,包括calladapter(回調(diào)類型),covertadapter(回調(diào)數(shù)據(jù)轉(zhuǎn)換)和okhttpcall綁定在一起。 - 當(dāng)篇文章簡單分析retrofit的實(shí)現(xiàn)能夠更有利于后面的retrofit的使用和學(xué)習(xí)retrofi的實(shí)現(xiàn)思路,后續(xù)兩個(gè)api就不跟了,后面注解的詳細(xì)解析及其串聯(lián)綁定,上面的流程也更流暢。
-
rotrofit如何實(shí)現(xiàn)同步和異步接口請求訪問的
retrofit的請求實(shí)現(xiàn)
-
由第二個(gè)小章節(jié)可以知道接口訪問retrofit最終是關(guān)聯(lián)到okhhtp,這個(gè)章節(jié)可以更好的驗(yàn)證retrofit將最后的接口請求還是交給okhttp處理的,首先看一下call的api集合:
call抽象接口如圖所示,接口中定義了兩個(gè)api一個(gè)是execute另一個(gè)是enqueue,這兩個(gè)表示同步和異步調(diào)用看api就和okhttp的同步/異步接口訪問很相似。
-
接下來重點(diǎn)去看call的okhhtp實(shí)現(xiàn)類okhttpcall對其api的實(shí)現(xiàn),即:okhhtpcall的execute的實(shí)現(xiàn)
????* okhhtpcall創(chuàng)建后只能執(zhí)行一次這個(gè)邏輯和okhhtp也很相似,第一步先是驗(yàn)重,校驗(yàn)當(dāng)前是否已經(jīng)執(zhí)行過。
????* 創(chuàng)建okhttp的call對象,createRawCall的具體實(shí)現(xiàn)是:
????* okhttpcall是否創(chuàng)建失敗根據(jù)其失敗類型返回不同的異常報(bào)警。
createRawCall的實(shí)現(xiàn)
????* 調(diào)用上面創(chuàng)建的okhttp3的call對象的execute方法將接口請求交接給okhhtp處理并獲取其response進(jìn)行后續(xù)的解析,解析流程下個(gè)章節(jié)再去分析。 - enqueue異步調(diào)用和同步execute流程基本類似。
-
okhttp響應(yīng)數(shù)據(jù)怎么轉(zhuǎn)換成為retrofit對象的
responce響應(yīng)解析
- 代碼比較簡單也比較清晰,就是對okhttp請求后的響應(yīng)數(shù)據(jù)進(jìn)行解析并根據(jù)不同的響應(yīng)碼對上層進(jìn)行響應(yīng),即:
????* http響應(yīng)碼成功都在200到300之間,所以不在此范圍內(nèi)的響應(yīng)接口失敗并將對應(yīng)的響應(yīng)數(shù)據(jù)對外提供
????* 204/205兩個(gè)響應(yīng)碼比較特殊,是接口成功但是沒有具體的響應(yīng)數(shù)據(jù),此時(shí)直接對外響應(yīng)成功并將數(shù)據(jù)對外響應(yīng),不進(jìn)行轉(zhuǎn)換。
????* 針對200的其他情況,將其封裝到ExceptionCatchingResponseBody中去,該封裝類持有responsebody并對其進(jìn)行讀取并獲取內(nèi)容類型和內(nèi)容大小,內(nèi)容不可讀則進(jìn)行異常抓取。
????* 上一步?jīng)]有出現(xiàn)異常的情況下進(jìn)行下一步的邏輯操作,將其交給轉(zhuǎn)換器進(jìn)行轉(zhuǎn)換操作。
????* 異常校驗(yàn)封裝類和平時(shí)寫法不太一樣,平時(shí)通常都是和下面的convert同時(shí)寫到一個(gè)try catch中去,仔細(xì)想想好像也沒什么不同。
????* 將轉(zhuǎn)換后的對象響應(yīng)給用戶。
















