查看Retrofit源码可知,其baseUrl为一个final修饰的HttpUrl类型的变量,所以不能也不可能有方法可以直接改掉BaseUrl。这时候我就想着可以通过反射入手去改掉这个值。所以有了如下代码。
val retrofit = ApiServiceFactory.instance.getRetrofit()::class.java
var baseUrlField = retrofit.getDeclaredField("baseUrl")
baseUrlField.isAccessible = true
val mRetrofit = ApiServiceFactory.instance.getRetrofit()
val nerBaseUrl = Retrofit.Builder().baseUrl(url).build().baseUrl()
baseUrlField.set(mRetrofit, nerBaseUrl)
然而事情并没有这么简单,如果你之前没有调用过网络请求,你会发现此代码是有效的,反之,你之前调用过的接口全部还是之前的baseUrl。为什么呢?经仔细查看源码后发现,Retrofit会把之前调用过的接口的一些信息通过一个Map对象缓存起来,在这些缓存信息中就有BaseUrl,所以这里虽然改成功了,但是看起来还是没有成功。所以我们需要把这个缓存的Map清空或者遍历这个Map,把缓存的BaseUrl都改掉。这里采用了把缓存的BaseUrl都改掉的方式。
原文这里是通过获取属性进行map遍历然后逐一修改,but问题来了,retrofit版本进行了升级,无法获取对应的属性.情况一时陷入了尴尬的境地.喝了一杯82年冰阔落,冷静思考了下,其实map清空也是可以的啊,于是.
try {
val retrofit = ApiServiceFactory.instance.getRetrofit()::class.java
var baseUrlField = retrofit.getDeclaredField("baseUrl")
baseUrlField.isAccessible = true
val mRetrofit = ApiServiceFactory.instance.getRetrofit()
val nerBaseUrl = Retrofit.Builder().baseUrl(url).build().baseUrl()
baseUrlField.set(mRetrofit, nerBaseUrl)
val serviceMethodCacheField = retrofit.getDeclaredField("serviceMethodCache")
serviceMethodCacheField.isAccessible = true
val serviceMethodCache: MutableMap<Method, Any> = serviceMethodCacheField[mRetrofit] as MutableMap<Method, Any>
serviceMethodCache.clear()
serviceMethodCacheField.set(mRetrofit, serviceMethodCache)
} catch (e: Exception) {
LoggerUtils.e(e.toString())
}
搞定,下班下班,回家回家
参考文档:https://blog.csdn.net/u014750748/article/details/82504082