一. Retrofit动态设置baseUrl有四种方式:
- 配置多个retrofit对象:即不同的 BaseUrl 使用不同的 Retrofit 对象来创建 ApiService 进行请求,这样只要新增一个不同的 BaseUrl ,那就需要重新创建一个新的 Retrofit 对象。
缺点:代码冗余,浪费资源,ApiService太多,不好管理。 - @Get , @Post 全路径:这些标注到每个接口方法上的注解不仅可以传相对路径,还可以传全路径,这样我们就可以做到不同的接口使用不同的 BaseUrl ,使用全路径的方式,从而达到使用多个 BaseUrl 的需求。
缺点:注解上的值只能是 Final 的常量,不能动态改变。因此只是相对动态。 - 使用Interceptor拦截器:动态改变每个 Request 的 Url 从而实现动态改变 BaseUrl。
缺点:个人觉得实现起来麻烦。 - 使用@url:Retrofit2官方为动态url带来的新的注解。
推荐使用。
二. 使用@url注意的地方:
- 请求方法注解如@GET,@POST,注解()不能携带值,只能单独使用。
/**
* 正确
* @param url
* @return
*/
@GET
Call<ResponseBody> yourGet(@Url String url);
/**
* 错误:@Url cannot be used with @GET URL
* @param url
* @return
*/
@GET("param")
Call<ResponseBody> yourGetParam(@Url String url);
- @url需要使用带host的全路径,否则不会更改baseUrl,只会和原baseUrl拼接在一起。
//原baseUrl:https://old.api.com/
apiService.yourGet("https://new.api.com/");
//实际的url:https://new.api.com/
apiService.yourGet("new.api.com/");
//实际的url:https://old.api.com/new.api.com/
- 正确使用示例
@POST
Call<ResponseBody> login(@Url String url, @Body Login login);
apiService.login("https://new.api.com/",login);
//这样就成功的动态改变了baseUrl
三. @url不改变baseUrl时的用法
像上面第二点说的,当@url不使用scheme+host全路径的用法时,我们在请求一些很长的url并且参数是固定的接口时,使用@url会很方便。
@GET
Call<ResponseBody> query(@Url String url
, @QueryMap Map<String, String> map);
Map<String, String> map = new HashMap<>();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
map.put("d", "4");
map.put("e", "5");
map.put("f", "6");
apiService.query("query", map);
//简单写法
@GET
Call<ResponseBody> query(@Url String url);
apiService.query("query?a=1&b=2&c=3&d=4&e=5&f=6");
特别需要注意的是:当我们在结点url上添加一个前置 / 符号时,每个加到host Url后面的东西都会被省略掉。建议在使用@url时,不要在结点url添加前置 / 符号 。
@GET
Call<ResponseBody> query(@Url String url);
//baseUrl:https://old.api.com/v2/
String url = "query?a=1";
apiService.query(url);
//实际url:https://old.api.com/v2/query?a=1
String url = "/query?a=1";
apiService.query(url);
//实际url:https://old.api.com/query?a=1
//这里url前置的"/"符号,会把baseUrl中host后面的"v2/"去掉