在 Android 应用中使用 动态域名 调用接口时,通常是为了灵活切换服务器地址(如多环境切换、灰度发布等)。以下是基于 Kotlin 和 OkHttp/Retrofit 的实现方案:
1. 动态域名管理类
创建一个单例类管理动态域名,支持实时更新:
object DynamicDomainManager {
private var currentDomain: String = "https://default.domain.com" // 默认域名
private val domainLock = ReentrantLock()
fun getDomain(): String {
return domainLock.withLock { currentDomain }
}
fun updateDomain(newDomain: String) {
domainLock.withLock {
currentDomain = newDomain
// 可选:持久化到 SharedPreferences 或其他存储
}
}
}
2. OkHttp 动态域名拦截器
通过拦截器在请求发出前动态替换域名:
class DynamicDomainInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val newUrl = originalRequest.url.newBuilder()
.host(DynamicDomainManager.getDomain().toHttpUrl().host) // 替换 Host
.build()
val newRequest = originalRequest.newBuilder()
.url(newUrl)
.build()
return chain.proceed(newRequest)
}
}
3. 配置 OkHttpClient
将拦截器添加到 OkHttpClient:
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(DynamicDomainInterceptor())
.build()
4. Retrofit 动态 BaseUrl 处理
如果使用 Retrofit,需动态设置 BaseUrl。使用 Retrofit.Builder 的 baseUrl 方法结合动态域名:
val retrofit = Retrofit.Builder()
.baseUrl(DynamicDomainManager.getDomain()) // 初始域名
.client(okHttpClient)
.build()
// 动态更新 Retrofit 的 BaseUrl(需重新构建 Retrofit 实例)
fun updateRetrofitDomain(newDomain: String) {
DynamicDomainManager.updateDomain(newDomain)
// 重新初始化 Retrofit 实例
}
5. 动态域名更新触发
在需要更新域名的地方(如从接口获取最新域名):
// 示例:从配置接口获取最新域名
apiService.getConfig().enqueue(object : Callback<ConfigResponse> {
override fun onResponse(call: Call<ConfigResponse>, response: Response<ConfigResponse>) {
val newDomain = response.body()?.domain
newDomain?.let { DynamicDomainManager.updateDomain(it) }
}
override fun onFailure(call: Call<ConfigResponse>, t: Throwable) {
// 处理失败
}
})
注意事项
-
线程安全:确保多线程环境下域名更新的原子性(如使用锁)。
-
HTTPS 证书:若动态域名使用不同证书,需配置
OkHttp的SSLContext。 -
缓存清理:域名更新后,清理
OkHttp的缓存(如连接池、DNS 缓存)。 -
兼容性:确保 Retrofit 的
@GET/@POST注解使用相对路径(非完整 URL)。

3324

被折叠的 条评论
为什么被折叠?



