开发中会遇到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