You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dagger Hilt单例场景下Retrofit拦截器读取SharedPreference始终返回旧值如何解决

问题根因

该问题与Hilt的单例注入逻辑无关,核心原因出在自定义SharedPrefs封装类的实现逻辑:

  1. 最常见的场景是SharedPrefs在初始化时一次性读取token值缓存到成员变量,后续调用getToken()直接返回缓存值,没有实时读取系统SharedPreference存储的最新值
  2. 少数场景为存储token时使用的SharedPreference实例与SharedPrefs内部依赖的实例参数不一致(比如文件名、访问模式不同)

修复方案

最优方案:修改SharedPrefs读取逻辑,每次调用实时取值

无需调整现有Hilt注入配置,直接修改SharedPrefs的getToken()方法,每次调用都从系统SharedPreference实例中读取最新值,不要将token缓存到成员变量中:

class SharedPrefs(private val context: Context) {
    // 仅全局持有系统SharedPreference实例即可,系统本身会保证内存缓存同步
    private val sp = context.getSharedPreferences("自定义SP存储文件名", Context.MODE_PRIVATE)

    // 错误示例:初始化时仅读取一次缓存到成员变量,后续取值不会更新
    // private val cachedToken = sp.getString("token", "")
    // fun getToken() = cachedToken ?: ""

    // 正确示例:每次调用都实时读取最新值
    fun getToken(): String {
        return sp.getString("token", "") ?: ""
    }

    // 存储token时也使用同一个sp实例
    fun saveToken(newToken: String) {
        sp.edit().putString("token", newToken).apply()
    }
}

同时需要确保存储token时,使用Hilt注入的SharedPrefs实例调用saveToken方法,不要自行创建SharedPrefs实例或者直接操作SharedPreference文件存储,避免两边实例不一致。

优化建议

建议给SharedPrefModule的提供方法加上@Singleton注解,保证全局只有一个SharedPrefs包装类实例,避免不必要的对象创建开销:

@Module
@InstallIn(SingletonComponent::class)
object SharedPrefModule {

    @Singleton
    @Provides
    fun provideSharedPref(@ApplicationContext context: Context) : SharedPrefs{
        return SharedPrefs(context)
    }
}

内容的提问来源于stack exchange,提问作者Prieyudha Akadita S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 19:15:09