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

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

前言

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

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

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

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

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

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

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

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

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

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

使用多 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


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

-- The end

相關文章
相關標籤/搜索