簡要分析Retrofit框架實(shí)現(xiàn)

retrofit整體代碼量不是很大,但是涉及到的知識點(diǎn)還是很多的,也是一款很好的解耦封裝框架,在其中是能夠?qū)W習(xí)到很多東西的,當(dāng)前鑒于時(shí)間原因先重點(diǎn)分析retrofit的流程邏輯實(shí)現(xiàn),里面的涉及到的知識點(diǎn)后續(xù)會(huì)有文章分析學(xué)習(xí)(水平有限,有些可能分析不到位,歡迎小伙伴指正討論,噴就沒必要了吧)。

  1. 從組建者模式淺談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è)對象做什么用:


    Platform的get api
    ????* get返回的靜態(tài)變量PLATFORM,找到改變量的初始化方法findPlatform();跟進(jìn)去方法如下:
    findPlatform()
    ????* api方法代碼很簡單也不麻煩就是校驗(yàn)了是否是Android平臺(tái)若Android平臺(tái)返回了Android對象,非Android平臺(tái)返回了platform示例,我們當(dāng)前分析Android,重點(diǎn)看一下Android對象的實(shí)現(xiàn),即:
    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í)例。
  1. 通過反射,注解,抽象代理等技術(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):
    validateServiceInterface
    ????* 如圖所示對于api的重點(diǎn)邏輯已做標(biāo)識處理,不再詳述,getTypeParameters
  • 通過抽象代理創(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)綁定,上面的流程也更流暢。
  1. 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í)行過。
    ????* okhttpcall是否創(chuàng)建失敗根據(jù)其失敗類型返回不同的異常報(bào)警。

    ????* 創(chuàng)建okhttp的call對象,createRawCall的具體實(shí)現(xiàn)是:
    createRawCall的實(shí)現(xiàn)

    ????* 調(diào)用上面創(chuàng)建的okhttp3的call對象的execute方法將接口請求交接給okhhtp處理并獲取其response進(jìn)行后續(xù)的解析,解析流程下個(gè)章節(jié)再去分析。
  • enqueue異步調(diào)用和同步execute流程基本類似。
  1. 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)給用戶。

參考文章:
retrofit相關(guān)源碼解析
深入淺出retrofit
深入讀懂retrofit

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容