解決Retrofit多BaseUrl及運行時動態改變BaseUrl(二)

原文地址: https://www.jianshu.com/p/35a8959c2f86git

前言

我在以前的文章 《解決Retrofit多BaseUrl及運行時動態改變BaseUrl》 中,介紹了市面上可以解決此類問題的 4 個常見的解決方案,並開源了本身通過優化後的解決方案 RetrofitUrlManager,如今再爲你們帶來此係列的第二篇文章,這篇文章主要介紹 RetrofitUrlManager 針對 BaseUrl 替換邏輯的重大升級,由於這個升級對於 RetrofitUrlManager 足夠重要,將使 RetrofitUrlManager 可以從容應對更多複雜的需求,因此單獨寫一篇文章讓更多的人可以知道github

Github : 您的 Star 是我堅持的動力 ✊api

爲何不使用多 Retrofit 實例的方案?

在上篇文章 《解決Retrofit多BaseUrl及運行時動態改變BaseUrl》 中,4 種方案的特色和不足我都描述的很清楚,建議沒看過這篇文章的能夠去看看這篇文章,擴寬知識面,在後面的時間裏常常有人問我爲何不使用多 Retrofit 實例的方案,多個 Retrofit 實例看起來並不會佔用多少資源啊?服務器

在回答以前爲了讓看這篇文章的人能瞭解我在說什麼,因此我再粘貼下 上篇文章 中關於這個方案的部分描述框架

民間經常使用解決方案:
以前也看過不少開源的聚合類 App 源碼, 像一些整合 知乎、 豆瓣、 Gank 等多個平臺數據的 App, 由於各自平臺的域名不一樣, 因此大多數這類 App 會給每一個平臺都各自建立一個 Retrofit 對象, 即不一樣的 BaseUrl 使用不一樣的 Retrofit 對象來建立 ApiService 進行請求, 這樣只要新增一個不一樣的 BaseUrl, 那就須要從新建立一個新的 Retrofit 對象post

我在這篇文章中從新回答下這個問題,爲每一個不一樣的 BaseUrl 都建立一個其餘配置屬性都如出一轍的 Retrofit 實例不止會形成資源的浪費,還會形成接口管理成本的增長,這個纔是最重要的一點, 舉個例學習

咱們平時項目中全部的 ApiService 都是使用同一個 Retrofit 實例的 Retrofit#create(ApiService) 方法進行實例化後開始接口的請求優化

可是當項目中出現多個 Retrofit 實例後,咱們在開發中不光要區分哪些接口使用哪一個 ApiService,還要區分哪些 ApiService 須要使用哪一個 Retrofit 實例進行實例化,若是 ApiService 使用錯誤的 Retrofit 實例進行實例化,那這個 ApiService 的全部接口請求都註定徹底失敗google

越複雜的項目,開發人數越多的項目,出錯的風險就越大,而且擴展性也在大打折扣,後面一有變動將會十分痛苦,隨着項目中接口的增長,以及 Retrofit 實例的增長 (BaseUrl 的增長),這個管理成本會成幾何倍的增長url

使用多 Retrofit 實例的方案前期投入成本太高,可能會影響以前項目管理接口的方式,某些封裝過 Retrofit 的項目,也可能須要大改,對於老項目的接入不利,而使用 RetrofitUrlManager 不只能夠知足多 BaseUrl 及運行時動態改變 BaseUrl 的需求,還具備熱插拔以及低侵入性的特色,在使用過程當中將不會影響到以前的接口管理方式和使用方式,還具備極強的擴展性,可應對後面陸續增長的極其複雜的 BaseUrl 替換需求

升級以前的 RetrofitUrlManager 的問題

這次升級以前的 RetrofitUrlManager 版本,只是將 上篇文章 的思想徹底實現,有了整個框架的基礎,可是在動態替換 BaseUrl 方面還不夠強大,最被你們吐槽的就是隻能替換 BaseUrl 的域名

好比一個須要替換 BaseUrlUrl 地址爲 "https:www.google.com/api/v2",其中 "https:www.google.com/api" 是咱們傳給 RetrofitBaseUrl,這時咱們使用 RetrofitUrlManager 框架,想把 BaseUrl 替換成 "https:www.github.com",咱們指望的替換後的 URL 地址是 "https:www.github.com/v2",但使用框架替換後的實際 URL 地址是 "https:www.github.com/api/v2", "/api" 做爲 BaseUrl 的一部分並無被新的 BaseUrl 替換掉,只是替換了 BaseUrl 中的域名

RetrofitUrlManager 是如何改善的

改善以前先要先分析爲何會這樣?由於 RetrofitUrlManager 框架在攔截器中攔截到的 URL 地址是 Retrofit 已經把 BaseUrl 和接口註解中的相對路徑合併後獲得的最終路徑地址,因此框架並不知道您傳給 RetrofitBaseUrl 除了域名外還包含後面的 "/api",框架不知道 BaseUrl 的具體值,因此框架只會默認全部的 BaseUrl 都只含有域名,因此也就只能替換域名

高級模式

想要解決此類問題也很簡單,告訴 RetrofitUrlManager 框架您傳給 RetrofitBaseUrl 具體值便可,因此框架升級後增長了 RetrofitUrlManager#startAdvancedModel(String) 方法,在 App 初始化時將您傳給 RetrofitBaseUrl 一樣傳給此方法,便可開啓高級模式,高級模式便可替換擁有多個 pathSegmentsBaseUrl,再也不侷限於只能替換域名

什麼是 pathSegment?

"https://www.github.com/wiki/part?name=jess" 中,其中的 "/wiki""/part" 就是 pathSegment, PathSize 就是 pathSegment 的個數

這個 URL 地址的 PathSize 就是 2, 第一個 pathSegment"/wiki",第二個 pathSegment"/part",能夠粗略的理解爲域名後面跟了幾個 "/" PathSize 就是幾

高級模式的替換規則

  1. URL 地址爲 "https://www.github.com/wiki/part",您在 App 初始化時傳入 RetrofitUrlManager#startAdvancedModel(String)BaseUrl"https://www.github.com/wiki",您想替換成的 BaseUrl 地址是 "https://www.google.com/api",通過框架替換後生成的最終 URL 地址爲 "http://www.google.com/api/part"

  2. URL 地址爲 "https://www.github.com/wiki/part",您在 App 初始化時傳入 RetrofitUrlManager#startAdvancedModel(String)BaseUrl"https://www.github.com/wiki",您想替換成的 BaseUrl 地址是 "https://www.google.com",通過框架替換後生成的最終 URL 地址爲 "http://www.google.com/part"

  3. URL 地址爲 "https://www.github.com/wiki/part", 您在 App 初始化時傳入 RetrofitUrlManager#startAdvancedModel(String)BaseUrl"https://www.github.com",您想替換成的 BaseUrl 地址是 "https://www.google.com/api",通過框架替換後生成的最終 URL 地址爲 "http://www.google.com/api/wiki/part"

超級模式

超級模式是高級模式的增強版,優先級高於高級模式,按理說高級模式就能知足開發中的大部分需求,那什麼又是超級模式呢?那就要先來講說高級模式了

高級模式的原理

在高級模式中您須要在 App 初始化時將您傳給 RetrofitBaseUrl 一樣傳給 RetrofitUrlManager#startAdvancedModel(String) 一份,用以開啓高級模式,成功開啓高級模式後,這個傳給 RetrofitUrlManager#startAdvancedModel(String)BaseUrl 就會做爲框架替換 BaseUrl 的基準

什麼叫做基準呢? 用此 BaseUrl 開啓高級模式,並不意味着框架就只能替換 域名"www.github.com" 前兩個 pathSegments"/wiki/part"URL,只要擁有域名以及大於或等於兩個 pathSegmentsURL 均可以被框架替換,所以高級模式只會保存傳入 RetrofitUrlManager#startAdvancedModel(String)BaseUrl 的格式 (保存 pathSegments 的個數),並非保存具體的值

高級模式的侷限

若是傳給 RetrofitUrlManager#startAdvancedModel(String)BaseUrl"https://www.github.com/wiki/part" (PathSize = 2),框架就會將項目中全部 URL 中的 域名 以及 域名 後面的前兩個 pathSegments 做爲可被替換的 BaseUrl 總體,意味着框架只會將 URL 中的 域名 以及前兩個 pathSegments 剪切並替換爲您指望的 BaseUrl

這時服務器忽然做出調整,項目中的一部分 URL 只須要將 "https://www.github.com/wiki" (PathSize = 1) 替換掉, 第二個 pathSegment "/part" 再也不做爲 BaseUrl 的一部分,不能被替換掉,必需要保留下來

這時項目中就出現了多個須要被替換的 BaseUrl 格式 (PathSize 不一樣),有些 URL 只須要替換 域名 以及前兩個 pathSegments,有些又只須要替換 域名 以及前一個 pathSegments,可是在開啓高級模式時,只保存了一個 BaseUrl 的格式,這時使用高級模式實現此需求就比較棘手

這個需求是一個比較變態的需求,可能不少人遇不上,可是我想讓您知道當您趕上了也不要怕,由於 RetrofitUrlManager 的超級模式已經幫您考慮周全

超級模式的用法

超級模式與高級模式不一樣的是,開啓超級模式並不須要調用 API,只需要在須要開啓超級模式的 Url 尾部加上 RetrofitUrlManager#IDENTIFICATION_PATH_SIZE (#baseurl_path_size=) + PathSize,這樣就明確的告訴了框架,在這個 URL 中須要被替換的 BaseUrl 含有幾個 pathSegments,至關於每一個 URL 均可以指定本身須要被替換的 BaseUrl 的格式,這樣就比高級模式只能在 App 初始化時,指定一個全局的 BaseUrl 格式靈活得多,若是當您開啓高級模式的同時也開啓了超級模式,因爲超級模式的優先級高於高級模式,因此只會執行超級模式

超級模式的替換規則

  1. URL 地址爲 "https://www.github.com/wiki/part#baseurl_path_size=1""#baseurl_path_size=1" 表示其中 BaseUrl"https://www.github.com/wiki",您想替換成的 BaseUrl 地址是 "https://www.google.com/api",通過框架替換後生成的最終 URL 地址爲 "http://www.google.com/api/part"

  2. URL 地址爲 "https://www.github.com/wiki/part#baseurl_path_size=1""#baseurl_path_size=1" 表示其中 BaseUrl"https://www.github.com/wiki",您想替換成的 BaseUrl 地址是 "https://www.google.com",通過框架替換後生成的最終 URL 地址爲 "http://www.google.com/part"

  3. URL 地址爲 "https://www.github.com/wiki/part#baseurl_path_size=0""#baseurl_path_size=0" 表示其中 BaseUrl"https://www.github.com",您想替換成的 BaseUrl 地址是 "https://www.google.com/api",通過框架替換後生成的最終 URL 地址爲 "http://www.google.com/api/wiki/part"

  4. URL 地址爲 "https://www.github.com/wiki/part/issues/1#baseurl_path_size=3""#baseurl_path_size=3" 表示其中 BaseUrl"https://www.github.com/wiki/part/issues",您想替換成的 BaseUrl 地址是 "https://www.google.com/api",通過框架替換後生成的最終 URL 地址爲 "http://www.google.com/api/1"

三種模式比較

在升級以前,框架就只有一個默認的普通模式 (只能替換域名),在升級以後新增了 高級模式超級模式,這兩個模式讓框架變得更增強大,在上面的內容中也詳細的介紹了這兩個模式,如今就來總結下這三個模式,讓你們可以按照本身的需求選擇出最適合的模式

替換 BaseUrl 的自由程度 (可擴展性)

普通模式 < 高級模式 < 超級模式

  • 普通模式: 只能替換域名

  • 高級模式: 只能替換在 RetrofitUrlManager#startAdvancedModel(String) 中傳入的固定 BaseUrl 格式

  • 超級模式: 每一個 URL 均可以隨意指定可被替換的 BaseUrl 格式

使用上的複雜程度

普通模式 < 高級模式 < 超級模式

  • 普通模式: 無需作過多配置

  • 高級模式: 在 App 初始化時調用一次 RetrofitUrlManager#startAdvancedModel(String) 便可

  • 超級模式: 每一個須要開啓超級模式的 URL 尾部都須要加入 RetrofitUrlManager#IDENTIFICATION_PATH_SIZE (#baseurl_path_size=) + PathSize

總結

因而可知,自由度越強,使用上也越複雜,因此能夠根據本身的需求選擇對應的模式,而且也能夠根據需求的變化隨意升級或降級這三種模式

此次更新讓 RetrofitUrlManager 的能力提高了一個檔次,足以應對各類複雜的 BaseUrl 替換需求,正由於 RetrofitUrlManager 極強的擴展性,如今甚至能夠作到,讓服務器能夠經過遠程動態控制項目中的多個 BaseUrl

若是還有什麼問題或者需求能夠給我提 Issues,若是 RetrofitUrlManager 可以給您帶來實質的幫助,也請不要吝嗇您的 Star

公衆號

掃碼關注個人公衆號 JessYan,一塊兒學習進步,若是框架有更新,我也會在公衆號上第一時間通知你們


Hello 我叫 JessYan,若是您喜歡個人文章,能夠在如下平臺關注我

-- The end

相關文章
相關標籤/搜索