前言
最近好几个朋友问我,多Url怎么处理,这里我们就说说这个。
- 【Android架构】基于MVP模式的Retrofit2+RXjava封装之多Url(七)
套路一
Retrofit2是支持全路径的,比如说
@GET("http://api.csslcloud.net/api/room/create") ObservablecreateRoom(@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(); ...省略代码... }复制代码
当然这里也就说说而已,估计没人会这么用...
套路三
大神曾提过另外一种方案,
思路是,通过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()); Listmark = 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(); } };复制代码
结果如下:
当然,这里是写死的判断,实际开发中,可能是提前知道或者接口返回具体哪些接口地址,可以存放在Map中,这里直接取值就好。
最后,献上源码
参考
RetrofitUrlManager
还提供了了更加丰富的替换规则,详情可以查看源码。