开发中会遇到URL需要动态切换,若你还是通过gradle打包切换是否不太灵活,下面将介绍一下retrofit基于OKhttp中动态修改URL;
原理添加拦截器,在retrofit中的现实更加灵活了如下代码:
1 2 private RetrofitUrlManager() { 3 if (!DEPENDENCY_OKHTTP) { //使用本框架必须依赖 Okhttp 4 throw new IllegalStateException("Must be dependency Okhttp"); 5 } 6 UrlParser urlParser = new DefaultUrlParser(); 7 urlParser.init(this); 8 setUrlParser(urlParser); 9 this.mInterceptor = new Interceptor() { 10 @Override 11 public Response intercept(Chain chain) throws IOException { 12 if (!isRun()) // 可以在 App 运行时, 随时通过 setRun(false) 来结束本框架的运行 13 return chain.proceed(chain.request()); 14 return chain.proceed(processRequest(chain.request())); 15 } 16 }; 17 }
下面是对retrofit设置的URL解析及添加到拦截器中
1 2 /** 3 * 对 {@link Request} 进行一些必要的加工, 执行切换 BaseUrl 的相关逻辑 4 * 5 * @param request {@link Request} 6 * @return {@link Request} 7 */ 8 public Request processRequest(Request request) { 9 if (request == null) return request; 10 11 Request.Builder newBuilder = request.newBuilder(); 12 13 String url = request.url().toString(); 14 //如果 Url 地址中包含 IDENTIFICATION_IGNORE 标识符, 框架将不会对此 Url 进行任何切换 BaseUrl 的操作 15 if (url.contains(IDENTIFICATION_IGNORE)) { 16 return pruneIdentification(newBuilder, url); 17 } 18 19 String domainName = obtainDomainNameFromHeaders(request); 20 21 HttpUrl httpUrl; 22 23 Object[] listeners = listenersToArray(); 24 25 // 如果有 header,获取 header 中 domainName 所映射的 url,若没有,则检查全局的 BaseUrl,未找到则为null 26 if (!TextUtils.isEmpty(domainName)) { 27 notifyListener(request, domainName, listeners); 28 httpUrl = fetchDomain(domainName); 29 newBuilder.removeHeader(DOMAIN_NAME); 30 } else { 31 notifyListener(request, GLOBAL_DOMAIN_NAME, listeners); 32 httpUrl = getGlobalDomain(); 33 } 34 35 if (null != httpUrl) { 36 HttpUrl newUrl = mUrlParser.parseUrl(httpUrl, request.url()); 37 if (debug) 38 Log.d(RetrofitUrlManager.TAG, "The new url is { " + newUrl.toString() + " }, old url is { " + request.url().toString() + " }"); 39 40 if (listeners != null) { 41 for (int i = 0; i < listeners.length; i++) { 42 ((onUrlChangeListener) listeners[i]).onUrlChanged(newUrl, request.url()); // 通知监听器此 Url 的 BaseUrl 已被切换 43 } 44 } 45 46 return newBuilder 47 .url(newUrl) 48 .build(); 49 } 50 51 return newBuilder.build(); 52 53 }
具体的使用,在retrofitAPI接口中添加@Headers({"Domain-Name: CONTROL"}) Domain-Name是key,CONTROL 设置的URL对应的key名称
1 /** 2 * ----------------------- 3 * @author: qiuxianfu 4 * @date: 2021/1/27 5 * ----------------------- 6 */ 7public interface PerformanceApi { 8 @Headers({"Domain-Name: CONTROL"}) 9 @POST("xxx/xxx/getSiteAreaPlanning") 10 Observable<PerformancesResponse> getDataList(@Query("userCode") String userCode); 11 12 @Headers({"Domain-Name: CONTROL"}) 13 @POST("xxx/xxx/addDutyRoster") 14 Observable<AddDutyTosterResponse> addDutyRoster(@Body AddDutyRosterRequest rosterRequest); 15 16}
这里就是动态设置了,CONTROL这个和@Headers({"Domain-Name: CONTROL"}) 保持一致
RetrofitUrlManager.getInstance().putDomain("CONTROL", InfieldAppUtils.getServerControlHttp()); } 地址:https://github.com/qxf323/RetrofitUrlManager