【Android架构】基于MVP模式的Retrofit2+RXjava封装之多Url(七)

前言

最近好几个朋友问我,多Url怎么处理,这里我们就说说这个。

  • 【Android架构】基于MVP模式的Retrofit2+RXjava封装(一)
  • 【Android架构】基于MVP模式的Retrofit2+RXjava封装之文件下载(二)
  • 【Android架构】基于MVP模式的Retrofit2+RXjava封装之文件上传(三)
  • 【Android架构】基于MVP模式的Retrofit2+RXjava封装之常见问题(四)
  • 【Android架构】基于MVP模式的Retrofit2+RXjava封装之断点下载(五)
  • 【Android架构】基于MVP模式的Retrofit2+RXjava封装之数据预处理(六)
  • 【Android架构】基于MVP模式的Retrofit2+RXjava封装之多Url(七)
  • 【Android架构】基于MVP模式的Retrofit2+RXjava封装之Token的刷新(八)

套路一

Retrofit2是支持全路径的,比如说

 @GET("http://api.csslcloud.net/api/room/create")
 Observable createRoom(@Path("param") String param);

所以,项目中只有个别接口需要的话,完全可以使用配置全路径这种方式。

套路二

保留多个Retrofit对象
在之前的代码中,Retrofit一直是单例的,这里我们可以创建2个Retrofit对象

  retrofit = new Retrofit.Builder()
                .baseUrl(BASE_SERVER_URL)
                .addConverterFactory(BaseConverterFactory.create())
                //支持RxJava2
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(client)
                .build();

        retrofit2 = new Retrofit.Builder()
                .baseUrl(BASE_SERVER_URL2)
                .addConverterFactory(BaseConverterFactory.create())
                //支持RxJava2
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(client)
                .build();

        apiServer = retrofit.create(ApiServer.class);

        apiServer2 = retrofit2.create(ApiServer.class);

然后在使用时,区分

    /**
     * 获取微分享列表
     */
    public void getShareList() {
        ...省略代码...
        ApiServer apiServer = ApiRetrofit2.getInstance().getApiService();
        ...省略代码...
    }

    /**
     * 获取微分享列表
     */
    public void getShareList2() {
      ...省略代码...
        ApiServer apiServer = ApiRetrofit2.getInstance().getApiService2();
        ...省略代码...
    }

当然这里也就说说而已,估计没人会这么用...

套路三

JessYan 大神曾提过另外一种方案,原文地址

思路是,通过Okhttp的拦截器,动态改变接口的地址,那拦截器里如何知道每个接口该使用哪个主地址呢?
这里可以使用head,请求时,添加固定的标志head,然后在拦截器中判断,完成替换。

如何实现

首先,在ApiServer 中定义接口,添加head

    /**
     * 获取分享列表
     *
     * @return
     */
    @FormUrlEncoded
    @POST("module/index.php?")
    @Headers({"url_mark:1"})
    Observable> getShareList2(@FieldMap Map map);

    /**
     * 获取分享列表
     *
     * @return
     */
    @FormUrlEncoded
    @POST("module/index.php?")
    @Headers({"url_mark:2"})
    Observable> getShareList3(@FieldMap Map map);

然后在Interceptor判断head

    private Interceptor interceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            Log.e(TAG, "----------Request Start----------------");
            Log.e(TAG, "| OldUrl=" + request.url().toString());
            List mark = request.headers("url_mark");

            HttpUrl newUrl = null;
            if (mark != null && mark.size() > 0) {
                Log.e(TAG, "| Head=" + mark.get(0));
                if (mark.get(0).equals("1")) {
                    newUrl = HttpUrl.parse("http://www.baidu.com/");
                } else if (mark.get(0).equals("2")) {
                    newUrl = HttpUrl.parse("http://www.github.com/");
                } else {
                    newUrl = request.url();
                }
                request = request.newBuilder().url(newUrl).build();
            }


            Log.e(TAG, "| NewUrl=" + request.url().toString());

            long startTime = System.currentTimeMillis();
            Response response = chain.proceed(request);
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            MediaType mediaType = response.body().contentType();
            String content = response.body().string();


            Log.e(TAG, "| " + request.toString());
            Log.e(TAG, "| Response:" + content);
            Log.e(TAG, "----------Request End:" + duration + "毫秒----------");
            return response.newBuilder()
                    .body(ResponseBody.create(mediaType, content))
                    .build();
        }
    };

结果如下:


image.png

当然,这里是写死的判断,实际开发中,可能是提前知道或者接口返回具体哪些接口地址,可以存放在Map中,这里直接取值就好。

最后,献上源码 Github

参考 RetrofitUrlManager

RetrofitUrlManager 还提供了了更加丰富的替换规则,详情可以查看源码。

你可能感兴趣的:(【Android架构】基于MVP模式的Retrofit2+RXjava封装之多Url(七))