解决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

相关文章
相关标签/搜索