Retrofit动态修改baseUrl,暨通过反射修改baseUrl

 查看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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Retrofit中,base URL是指用于构建网络请求的基本URL地址。在Kotlin代码中的`retrofit.kt`文件,`baseurl`应该是一个变量,用于存储base URL的值。 在Retrofit中,通常我们会创建一个单例的Retrofit实例,通过调用其`baseUrl()`方法来设置base URL。例如: ```kotlin object RetrofitInstance { private const val BASE_URL = "https://api.example.com/" val retrofit: Retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build() } ``` 在上面的例子中,`BASE_URL`即为我们设置的base URL,它是一个字符串常量,指定了API的根地址。我们使用`Retrofit.Builder().baseUrl(BASE_URL)`来创建一个Retrofit实例,该实例会将所有的网络请求都基于这个base URL进行构建。 基本URL通常包含协议(例如http或https),主机地址(例如api.example.com),可选的端口号,以及其他路径或查询参数。将这些信息作为base URL来设置,可以方便地在请求时构建完整的URL。 使用这种方式设置base URL,可以让我们在应用中的各个网络请求中使用相对地址,而不需要每次都指定完整的请求URL。这样可以简化代码,并提高维护性。 总结来说,在`retrofit.kt`文件中的`baseurl`是用来存储base URL的变量,通常以字符串的形式表示API的根地址。在创建Retrofit实例时,会将这个base URL传递给`Retrofit.Builder().baseUrl()`方法来设置。这个base URL会在所有网络请求中作为基础地址使用,便于构建完整的请求URL。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值