Android Hilt初始化后如何更新已注入的token等依赖值
问题根源
你当前的实现中,ActivityRetainedComponent作用域的依赖在对应Activity的完整生命周期内只会初始化一次,你在构造OkHttp拦截器时直接传入了依赖初始化阶段读取的固定token值。后续登录完成更新token后,已经创建完成的拦截器、OkHttpClient、Retrofit、Api Service实例都不会自动更新持有的token,早于登录创建的ViewModel持有旧的服务实例,自然无法携带新token。
方案1:改造拦截器动态拉取最新Token(最推荐)
无需修改现有依赖注入结构,也不需要刷新已注入实例,只需调整拦截器的token读取逻辑,每次请求时实时获取最新token即可。
修改步骤:
- 重构
HttpRequestInterceptor,取消构造函数传入固定token,改为每次请求时读取最新值:
class HttpRequestInterceptor @Inject constructor( @ApplicationContext private val context: Context ) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val requestBuilder = chain.request().newBuilder() // 每次发起请求时实时读取最新存储的token val latestToken = context.getToken() if (latestToken.isNotBlank()) { requestBuilder.addHeader("Authorization", "Bearer $latestToken") } return chain.proceed(requestBuilder.build()) } }
- 调整
NetworkModule中OkHttpClient的提供逻辑:
@Provides fun provideOkHttpClient(interceptor: HttpRequestInterceptor): OkHttpClient { return OkHttpClient.Builder() .addInterceptor(interceptor) .build() } // 原有的provideToken方法可以直接删除,无需单独注入token字符串
登录成功后只需将新token存入原有的存储位置(即context.getToken()对应的存储源,如SharedPreferences、MMKV等),后续所有请求会自动携带最新token,完全不需要修改已注入的ViewModel或服务实例。
方案2:强制刷新已注入依赖(不推荐,性能开销更高)
如果你有特殊场景必须更新已注入的依赖实例,可以选择以下实现方式:
- 调整网络相关依赖的作用域为更小的
FragmentComponent,登录完成后重建当前Fragment,Hilt会自动重新构建所有依赖,读取最新token - 采用
Provider懒加载依赖,每次请求时拉取新的服务实例:- 移除NetworkModule中所有网络依赖的单例注解,让依赖每次注入都生成新实例
- 修改ViewModel注入逻辑:
@HiltViewModel class ProductsCategoryViewModel @Inject constructor( private val serviceProvider: Provider<CartService>, private val mainRepository: MainRepository ) : BaseViewModel() { suspend fun requestData() { // 每次请求前获取最新的服务实例 val latestService = serviceProvider.get() latestService.requestApi() } }
该方案会频繁创建OkHttpClient、Retrofit实例,存在不必要的性能损耗,优先选择方案1即可覆盖99%的场景。
内容的提问来源于stack exchange,提问作者abdulrahman kassem
相关产品推荐
相关产品推荐

