共享偏好总是在改装拦截器中获得旧价值

Shared Preference Always Get Old Value In Retrofit Interceptor

我是匕首柄的新手。所以我刚刚创建了一个与 Application (SingletonComponent) 一样的模块,就像这样。

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

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

然后像这样在网络模块中使用SharedPref。 (见prefs参数)

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

    @Singleton
    @Provides
    fun provideRetrofit(okHttp: OkHttpClient) : Retrofit {
        return Retrofit.Builder().apply {
            addConverterFactory(GsonConverterFactory.create())
            addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            client(okHttp)
            baseUrl(BuildConfig.API_BASE_URL)
        }.build()
    }

    @Singleton
    @Provides
    fun provideOkHttp(pref: SharedPrefs) : OkHttpClient {
        return OkHttpClient.Builder().apply {
            connectTimeout(60, TimeUnit.SECONDS)
            readTimeout(60, TimeUnit.SECONDS)
            writeTimeout(60, TimeUnit.SECONDS)
            addInterceptor(RequestInterceptor(pref))
        }.build()
    }

}

RequestInterceptor 内部是这样的:

class RequestInterceptor(private val pref: SharedPrefs) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val token = pref.getToken()
        val newRequest = chain.request().newBuilder()
            .addHeader("Authorization", token)
            .build()
        return chain.proceed(newRequest)
    }
}

我在没有登录的情况下启动应用程序(这意味着 prefs.getToken())将 return 清空。但问题是,即使我已经登录并成功保存了令牌,pref.getToken() 仍然是 return 空的。我认为实例化 sharedPrefs 存在问题,因为它是单例的。

但是我如何刷新共享首选项实例,以便拦截器始终获得共享首选项的更新值?

如果我想获取共享首选项的新值以便拦截器可以工作,我需要关闭应用程序然后从任务管理器swipe/clear

我通过在网络模块中添加这个来修复

    @Provides
    fun provideRequestInterceptor(prefs: SharedPrefs) : RequestInterceptor {
        return RequestInterceptor(prefs)
    }

和这样的 RequestInterceptor:

class RequestInterceptor constructor(private val pref: SharedPrefs) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val token = pref.getToken()
        val newRequest = chain.request().newBuilder()
            .addHeader("Authorization", token)
            .build()
        return chain.proceed(newRequest)
    }
}

然后在提供 okHttpClient 时,我将函数更改为:

    @Singleton
    @Provides
    fun provideOkHttp(requestInterceptor: RequestInterceptor) : OkHttpClient {
        return OkHttpClient.Builder().apply {
            connectTimeout(60, TimeUnit.SECONDS)
            readTimeout(60, TimeUnit.SECONDS)
            writeTimeout(60, TimeUnit.SECONDS)
            addInterceptor(requestInterceptor)
        }.build()
    }