Retrofit 动态修改BaseUrl 操作

简介: Retrofit 动态修改BaseUrl 操作

开发中会遇到URL需要动态切换,若你还是通过gradle打包切换是否不太灵活,下面将介绍一下retrofit基于OKhttp中动态修改URL;

原理添加拦截器,在retrofit中的现实更加灵活了如下代码:

    private RetrofitUrlManager() {
            if (!DEPENDENCY_OKHTTP) { //使用本框架必须依赖 Okhttp
                throw new IllegalStateException("Must be dependency Okhttp");
            }
            UrlParser urlParser = new DefaultUrlParser();
            urlParser.init(this);
            setUrlParser(urlParser);
            this.mInterceptor = new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    if (!isRun()) // 可以在 App 运行时, 随时通过 setRun(false) 来结束本框架的运行
                        return chain.proceed(chain.request());
                    return chain.proceed(processRequest(chain.request()));
                }
            };
        }

    下面是对retrofit设置的URL解析及添加到拦截器中

      /**
           * 对 {@link Request} 进行一些必要的加工, 执行切换 BaseUrl 的相关逻辑
           *
           * @param request {@link Request}
           * @return {@link Request}
           */
          public Request processRequest(Request request) {
              if (request == null) return request;
              Request.Builder newBuilder = request.newBuilder();
              String url = request.url().toString();
              //如果 Url 地址中包含 IDENTIFICATION_IGNORE 标识符, 框架将不会对此 Url 进行任何切换 BaseUrl 的操作
              if (url.contains(IDENTIFICATION_IGNORE)) {
                  return pruneIdentification(newBuilder, url);
              }
              String domainName = obtainDomainNameFromHeaders(request);
              HttpUrl httpUrl;
              Object[] listeners = listenersToArray();
              // 如果有 header,获取 header 中 domainName 所映射的 url,若没有,则检查全局的 BaseUrl,未找到则为null
              if (!TextUtils.isEmpty(domainName)) {
                  notifyListener(request, domainName, listeners);
                  httpUrl = fetchDomain(domainName);
                  newBuilder.removeHeader(DOMAIN_NAME);
              } else {
                  notifyListener(request, GLOBAL_DOMAIN_NAME, listeners);
                  httpUrl = getGlobalDomain();
              }
              if (null != httpUrl) {
                  HttpUrl newUrl = mUrlParser.parseUrl(httpUrl, request.url());
                  if (debug)
                      Log.d(RetrofitUrlManager.TAG, "The new url is { " + newUrl.toString() + " }, old url is { " + request.url().toString() + " }");
                  if (listeners != null) {
                      for (int i = 0; i < listeners.length; i++) {
                          ((onUrlChangeListener) listeners[i]).onUrlChanged(newUrl, request.url()); // 通知监听器此 Url 的 BaseUrl 已被切换
                      }
                  }
                  return newBuilder
                          .url(newUrl)
                          .build();
              }
              return newBuilder.build();
          }

      具体的使用,在retrofitAPI接口中添加@Headers({"Domain-Name: CONTROL"}) Domain-Name是key,CONTROL 设置的URL对应的key名称

        /**
         * -----------------------
         * @author: qiuxianfu
         * @date: 2021/1/27
         * -----------------------
         */
        public interface PerformanceApi {
            @Headers({"Domain-Name: CONTROL"})
            @POST("xxx/xxx/getSiteAreaPlanning")
            Observable<PerformancesResponse> getDataList(@Query("userCode") String userCode);
            @Headers({"Domain-Name: CONTROL"})
            @POST("xxx/xxx/addDutyRoster")
            Observable<AddDutyTosterResponse> addDutyRoster(@Body AddDutyRosterRequest rosterRequest);
        }

        这里就是动态设置了,CONTROL这个和@Headers({"Domain-Name: CONTROL"}) 保持一致


        RetrofitUrlManager.getInstance().putDomain("CONTROL", InfieldAppUtils.getServerControlHttp()); }

        地址:https://github.com/qxf323/RetrofitUrlManager

        相关文章
        Flutter Getx 路由 until 方法帮助你跳转指定路由
        不少同学都会问我,这样一个场景,当我点击商品列表,进入商品页,点击购买,支付成功后,想返回商品页,或者我的中心的订单列表。怎么做,这中间跨度了 n 个路由。 我不只一次的推荐 GetX 的 until 方法,和 offNamedUntil 方法。 我写了个 demo 今天我们就一起来看下这两个方法如何使用。
        2042 0
        Flutter Getx 路由 until 方法帮助你跳转指定路由
        |
        缓存 Java Maven
        如何在 Java 镜像构建过程中免重复下载依赖包
        利用镜像构建缓存机制来加速 Java 镜像构建过程,免重复下载依赖包。
        3616 0
        如何在 Java 镜像构建过程中免重复下载依赖包
        |
        网络安全
        charles抓包显示乱码解决方法
        【问题现象】 在抓https协议请求时,Request和Response显示乱码了: 【解决办法】 第一步:点击 【工具栏-->Proxy-->SSL Proxying Settings...】   第二点:添加需求抓包的请求的域名和端口号:   重新抓包,Request显示正常:   PS: 问题解决起来并没有太复杂,不过在网上搜索的资料试过很多都没有起做用,遂在此做个记录。
        10279 0
        |
        API Android开发 容器
        33. 【Android教程】悬浮窗:PopupWindow
        33. 【Android教程】悬浮窗:PopupWindow
        1897 2
        |
        JSON Java 定位技术
        【Android App】GPS获取定位经纬度和根据经纬度获取详细地址讲解及实战(附源码和演示 超详细)
        【Android App】GPS获取定位经纬度和根据经纬度获取详细地址讲解及实战(附源码和演示 超详细)
        4170 1
        |
        SQL 分布式计算 HIVE
        基于 Kyuubi 实现分布式 Flink SQL 网关
        本文整理自网易互娱资深开发工程师、Apache Kyuubi Committer 林小铂的《基于 Kyuubi 实现分布式 Flink SQL 网关》分享。
        105068 64
        基于 Kyuubi 实现分布式 Flink SQL 网关
        |
        12月前
        |
        Android开发 开发者
        Android面试之Activity启动流程简述
        每个Android开发者都熟悉的Activity,但你是否了解它的启动流程呢?本文将带你深入了解。启动流程涉及四个关键角色:Launcher进程、SystemServer的AMS、应用程序的ActivityThread及Zygote进程。核心在于AMS与ActivityThread间的通信。文章详细解析了从Launcher启动Activity的过程,包括通过AIDL获取AMS、Zygote进程启动以及ActivityThread与AMS的通信机制。接着介绍了如何创建Application及Activity的具体步骤。整体流程清晰明了,帮助你更深入理解Activity的工作原理。
        229 0
        |
        Web App开发 存储 网络安全
        Charles抓包神器的使用,完美解决抓取HTTPS请求unknown问题
        本文介绍了在 Mac 上使用的 HTTP 和 HTTPS 抓包工具 Charles 的配置方法。首先,强调了安装证书对于抓取 HTTPS 请求的重要性,涉及 PC 和手机端。在 PC 端,需通过 Charles 软件安装证书,然后在钥匙串访问中设置为始终信任。对于 iOS 设备,需设置 HTTP 代理,通过电脑上的 IP 和端口访问特定网址下载并安装证书,同时在设置中信任该证书。配置 Charles 包括设置代理端口和启用 SSL 代理。完成这些步骤后,即可开始抓包。文章还提及 Android 7.0 以上版本可能存在不信任用户添加 CA 证书的问题,但未提供解决办法。
        4169 0
        Charles抓包神器的使用,完美解决抓取HTTPS请求unknown问题
        |
        API
        Camera2预览方向、拍照方向设置
        Camera2预览方向、拍照方向设置
        972 2
        |
        人工智能 Java
        通过okhttp调用SSE流式接口,并将消息返回给客户端
        通过okhttp调用SSE流式接口,并将消息返回给客户端