Retrofit反射修改baseUrl
背景:Android开发时,需要两个平台切换,项目中网络请求是用的Retrofit这块,发现没有直接切换的接口,百度一下,大部分直接是通过拦截器里面进行切换,说Retrofit中baseUrl是final类型,不能反射修改。通过测试后发现final值是可以修改的(包括基本类型),但是final值的初始化要在构造方法中赋值。
解决思路:
+. 直接替换掉Retrofit中的baseUrl
public final class Retrofit {
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
final okhttp3.Call.Factory callFactory;
final HttpUrl baseUrl;
final List<Converter.Factory> converterFactories;
final List<CallAdapter.Factory> callAdapterFactories;
final @Nullable Executor callbackExecutor;
final boolean validateEagerly;反射替换代码如下:
//baseUrl:切换的url
//retrofit:对于的Retrofit实例
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
Field field = retrofit.getClass().getDeclaredField("baseUrl");
field.setAccessible(true);
field.set(retrofit, httpUrl);单点可以跟踪查看,retrofit中的baseUrl确实已经替换成功,但是去请求数据时,发现还是之前的数据。
具体原因跟踪源码:
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
Retrofit会根据Method缓存请求,如果之前请求过,就是你切换了baseUrl,请求同个Method,那还是之前的,对于这样,把对应的缓存清理下就行。
field = retrofit.getClass().getDeclaredField("serviceMethodCache");
field.setAccessible(true);
Map serviceMethodCache = (Map) field.get(retrofit);
serviceMethodCache.clear();再测试下,可以成功切换。
完整代码如下:
public static void baseUrl(Retrofit retrofit, String baseUrl) throws Exception {
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
Field field = retrofit.getClass().getDeclaredField("baseUrl");
field.setAccessible(true);
field.set(retrofit, httpUrl);
field = retrofit.getClass().getDeclaredField("serviceMethodCache");
field.setAccessible(true);
Map serviceMethodCache = (Map) field.get(retrofit);
serviceMethodCache.clear();
}当网络请求正在进行时,这种暴力切换方式,可能会有些意想不到的问题,至于其它问题,后续发现追加。
相关推荐
smaillift 2020-02-17
霸气的名字 2020-02-15
RikkaTheWorld 2019-12-08
TOmyhonour 2019-11-08
齐天大圣数据候 2019-10-31
kcstrong 2019-10-19
冰川孤辰 2019-09-08
kangtingting0 2019-09-07
俊光 2018-08-10
俊光 2019-07-30
xzw 2019-07-01
smaillift 2019-07-01
javashu0 2019-07-01
needh 2019-06-30
kcstrong 2019-06-28
qjbagu 2016-04-05
霸气的名字 2019-06-27
RikkaTheWorld 2019-06-27