Android中如何通过Hilt重新初始化Retrofit单例?
解决Hilt中Retrofit单例baseUrl更新不生效的问题
方案一:使用OkHttp拦截器动态替换BaseUrl(推荐)
这种方案无需重新创建Retrofit实例,而是在每次发起请求时自动读取最新的Url并替换,无需重启应用。
- 编写动态BaseUrl拦截器
public class DynamicBaseUrlInterceptor implements Interceptor { private final SharedPrefManager sharedPrefManager; public DynamicBaseUrlInterceptor(SharedPrefManager sharedPrefManager) { this.sharedPrefManager = sharedPrefManager; } @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); String newBaseUrl = sharedPrefManager.getUrl(); HttpUrl originalHttpUrl = originalRequest.url(); HttpUrl newHttpUrl = HttpUrl.parse(newBaseUrl); // 仅当BaseUrl发生变化时执行替换 if (newHttpUrl != null && !originalHttpUrl.host().equals(newHttpUrl.host())) { HttpUrl updatedUrl = newHttpUrl.newBuilder() .encodedPath(originalHttpUrl.encodedPath()) .encodedQuery(originalHttpUrl.encodedQuery()) .build(); Request updatedRequest = originalRequest.newBuilder().url(updatedUrl).build(); return chain.proceed(updatedRequest); } return chain.proceed(originalRequest); } }
- 修改ApiNetworkModule配置
给OkHttpClient添加拦截器,同时Retrofit的baseUrl可以设置一个占位符(实际请求会被拦截器替换):
@Module @InstallIn(SingletonComponent.class) public class ApiNetworkModule { @Singleton @Provides public OkHttpClient provideOkHttpClient(SharedPrefManager sharedPrefManager) { return new OkHttpClient.Builder() .addInterceptor(new DynamicBaseUrlInterceptor(sharedPrefManager)) // 补充其他OkHttp配置(超时、日志拦截器等) .build(); } @Singleton @Provides public Retrofit provideRetrofit(OkHttpClient okHttpClient, Gson gson) { return new Retrofit.Builder() .client(okHttpClient) .baseUrl("https://placeholder.com/") // 占位符BaseUrl .addConverterFactory(GsonConverterFactory.create(gson)) .build(); } }
方案二:手动管理Retrofit实例,Url更新时重建
如果需要强制重建Retrofit单例,可以通过自定义管理器类手动控制实例生命周期:
- 创建Retrofit管理器类
public class RetrofitManager { private Retrofit retrofit; private final OkHttpClient okHttpClient; private final Gson gson; private final SharedPrefManager sharedPrefManager; @Inject public RetrofitManager(OkHttpClient okHttpClient, Gson gson, SharedPrefManager sharedPrefManager) { this.okHttpClient = okHttpClient; this.gson = gson; this.sharedPrefManager = sharedPrefManager; createRetrofit(); // 初始化第一个实例 } private void createRetrofit() { retrofit = new Retrofit.Builder() .client(okHttpClient) .baseUrl(sharedPrefManager.getUrl()) .addConverterFactory(GsonConverterFactory.create(gson)) .build(); } // Url更新后调用此方法重建Retrofit public void refreshRetrofit() { createRetrofit(); } public Retrofit getRetrofit() { return retrofit; } }
- 修改Hilt模块配置
提供RetrofitManager单例,并通过它提供Retrofit实例:
@Module @InstallIn(SingletonComponent.class) public class ApiNetworkModule { @Singleton @Provides public RetrofitManager provideRetrofitManager(OkHttpClient okHttpClient, Gson gson, SharedPrefManager sharedPrefManager) { return new RetrofitManager(okHttpClient, gson, sharedPrefManager); } @Provides public Retrofit provideRetrofit(RetrofitManager retrofitManager) { return retrofitManager.getRetrofit(); } }
- Url更新时触发重建
在保存新Url的逻辑中调用刷新方法:
// 示例:设置页面保存新Url后 sharedPrefManager.saveNewUrl(newUrl); retrofitManager.refreshRetrofit();
注意:此方案中,已创建的Retrofit Service实例不会自动更新,需要重新调用
retrofit.create(Service.class)获取新实例才能使用新Url。
内容的提问来源于stack exchange,提问作者Alex D.
相关产品推荐
相关产品推荐

