在使用 Retrofit 进行网络请求时,我们可能会遇到需要动态修改 baseUrl 的情况。但是,有时候即使我们在代码中使用了 retrofit.baseUrl()
方法来修改 baseUrl,但实际生效的却是初始化时设置的 baseUrl。这是因为 Retrofit 在初始化时会对 baseUrl 进行一次不可更改的赋值,之后的调用只会影响到相对路径的拼接。
那么,如何解决这个问题呢?
解决方案
下面给出两种解决方案,你可以根据实际情况选择适合自己的方法。
1. 使用 DynamicUrlInterceptor
这是一种比较简单的解决方案,我们可以通过实现一个自定义的拦截器来动态修改 baseUrl,并且在每次请求前将其设置到 Retrofit 中。
我们先定义一个 DynamicUrlInterceptor
类:
public class DynamicUrlInterceptor implements Interceptor {
private String mBaseUrl;
public DynamicUrlInterceptor(String baseUrl) {
mBaseUrl = baseUrl;
}
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Request originalRequest = chain.request();
String url = originalRequest.url().toString();
if (!url.startsWith(mBaseUrl)) {
HttpUrl newUrl = HttpUrl.parse(mBaseUrl + originalRequest.url().encodedPath());
Request newRequest = originalRequest.newBuilder().url(newUrl).build();
return chain.proceed(newRequest);
} else {
return chain.proceed(originalRequest);
}
}
}
然后,在创建 Retrofit 实例时,添加这个拦截器:
Interceptor dynamicUrlInterceptor = new DynamicUrlInterceptor(yourDynamicBaseUrl);
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addInterceptor(dynamicUrlInterceptor);
Retrofit retrofit = new Retrofit.Builder()
.client(builder.build())
.baseUrl(yourInitialBaseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
这样,在每次请求前,DynamicUrlInterceptor
都会检查请求的 url 是否以动态 baseUrl 开头,如果不是则会重新构建一个新的请求,并将动态 baseUrl 加上去。
2. 自定义 Retrofit 实例管理类
如果你的项目中有多个 Retrofit 实例,并且每个实例所需的动态 baseUrl 都不一样,那么可以考虑使用一个自定义的 Retrofit 实例管理类。这样可以更方便地管理和切换不同的 baseUrl。
首先,我们创建一个 RetrofitManager
类:
public class RetrofitManager {
private Map<String, Retrofit> mRetrofitMap = new HashMap<>();
public Retrofit createRetrofit(String baseUrl) {
if (mRetrofitMap.containsKey(baseUrl)) {
return mRetrofitMap.get(baseUrl);
} else {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
mRetrofitMap.put(baseUrl, retrofit);
return retrofit;
}
}
public void resetBaseUrl(String baseUrl, Retrofit retrofit) {
retrofit.baseUrl().newBuilder().scheme(baseUrl).build();
}
}
然后,在使用 Retrofit 的地方,我们可以这样来进行管理和切换 baseUrl:
RetrofitManager retrofitManager = new RetrofitManager();
Retrofit retrofit = retrofitManager.createRetrofit(yourInitialBaseUrl);
// 发起请求
...
// 在需要修改 baseUrl 的时候,调用 resetBaseUrl() 方法重新设置 baseUrl
Retrofit newRetrofit = retrofitManager.resetBaseUrl(yourDynamicBaseUrl, retrofit);
// 发起新的请求
...
通过这种方式,我们可以灵活地管理和切换 baseUrl,每个 Retrofit 实例都有独立的 baseUrl,而互不干扰。
总结
在 Android Retrofit 中动态修改 baseUrl 的问题可以通过自定义拦截器或使用一个 Retrofit 实例管理类来解决。使用这两种方法之一,你可以根据实际需要在运行时动态切换 baseUrl,提升应用的灵活性和扩展性。
希望这篇博客对你有所帮助,如果有任何问题或建议,请留言讨论。
本文来自极简博客,作者:深海鱼人,转载请注明原文链接:Android Retrofit修改baseUrl不生效问题