如何重新初始化 Hilt dagger 中的 Singleton 组件?
How can i reinitialise the Singleton Component in Hilt dagger?
我的项目中有一个改造模块,登录前我想使用没有 headers 的改造,但登录后我想使用 Hilt Dagger headers 使用改造。我该怎么做?
@Module
@InstallIn(SingletonComponent::class)
object RetrofitDi {
@Provides
fun getBasePath(): String {
return "http://abcd.com/"
}
@Provides
fun providesLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
}
@Provides
fun providesOkHttpClients(@ApplicationContext context: Context, sharedPreference: SharedPreference, httpLoggingInterceptor: HttpLoggingInterceptor): OkHttpClient {
val okhttpClient = OkHttpClient.Builder()
okhttpClient.addInterceptor(httpLoggingInterceptor)
okhttpClient.callTimeout(60, TimeUnit.SECONDS)
okhttpClient.connectTimeout(60, TimeUnit.SECONDS)
okhttpClient.writeTimeout(60, TimeUnit.SECONDS)
okhttpClient.readTimeout(60, TimeUnit.SECONDS)
val token = sharedPreference.getStringData(SharedPreference.AUTH_KEY)
val user_id = sharedPreference.getStringData(SharedPreference.USER_ID)
if (BuildConfig.DEBUG) {
val interceptor = HttpLoggingInterceptor()
interceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS)
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
okhttpClient.addInterceptor(interceptor)
okhttpClient.addInterceptor(Interceptor { chain ->
val response = chain.proceed(chain.request())
if (!response.isSuccessful) {
when (response.code) {
CommonUtils.ALREADY_LOGGED_IN -> {
sharedPreference.setBoolean(SharedPreference.IS_LOGGED_IN, false)
sharedPreference.clear()
context.getCacheDir().delete()
val intent = Intent(context, LoginActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
}
}
response
})
}
okhttpClient.addInterceptor(Interceptor { chain: Interceptor.Chain ->
val builder1 = chain.request().newBuilder()
var request: Request? = null
if (!token.isEmpty()) {
builder1.addHeader("auth_key", "" + token)
}
if (!user_id.isEmpty()) {
builder1.addHeader("user_id", "" + user_id)
}
request = builder1.build()
chain.proceed(request)
})
return okhttpClient.build()
}
@Provides
fun providesGSONConvertorFactory(): Converter.Factory {
return GsonConverterFactory.create()
}
@Provides
fun providesRetrofit(baseUrl: String, convertor: Converter.Factory, okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder().baseUrl(baseUrl).addConverterFactory(convertor).client(okHttpClient).build()
}
@Provides
fun providesApiService(retrofit: Retrofit): ApiService {
return retrofit.create(ApiService::class.java)
}
}
在 hilt-dagger 中创建了一次单例实例,但令牌和 user_id 将在登录后可用。登录后我需要新的 okhttpclient。我在没有 DI 的情况下做到了。但是不知道如何处理 hilt-dagger.
更好的方法是让您的 API 服务方法为需要令牌的 API 注释 @Headers("Token-required")
。然后在您的拦截器方法中检查此 header 为:
if (request.header("Token-required") != null) {
request = request.newBuilder()
.addHeader("token", "your token value")
.build()
}
我的项目中有一个改造模块,登录前我想使用没有 headers 的改造,但登录后我想使用 Hilt Dagger headers 使用改造。我该怎么做?
@Module
@InstallIn(SingletonComponent::class)
object RetrofitDi {
@Provides
fun getBasePath(): String {
return "http://abcd.com/"
}
@Provides
fun providesLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
}
@Provides
fun providesOkHttpClients(@ApplicationContext context: Context, sharedPreference: SharedPreference, httpLoggingInterceptor: HttpLoggingInterceptor): OkHttpClient {
val okhttpClient = OkHttpClient.Builder()
okhttpClient.addInterceptor(httpLoggingInterceptor)
okhttpClient.callTimeout(60, TimeUnit.SECONDS)
okhttpClient.connectTimeout(60, TimeUnit.SECONDS)
okhttpClient.writeTimeout(60, TimeUnit.SECONDS)
okhttpClient.readTimeout(60, TimeUnit.SECONDS)
val token = sharedPreference.getStringData(SharedPreference.AUTH_KEY)
val user_id = sharedPreference.getStringData(SharedPreference.USER_ID)
if (BuildConfig.DEBUG) {
val interceptor = HttpLoggingInterceptor()
interceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS)
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
okhttpClient.addInterceptor(interceptor)
okhttpClient.addInterceptor(Interceptor { chain ->
val response = chain.proceed(chain.request())
if (!response.isSuccessful) {
when (response.code) {
CommonUtils.ALREADY_LOGGED_IN -> {
sharedPreference.setBoolean(SharedPreference.IS_LOGGED_IN, false)
sharedPreference.clear()
context.getCacheDir().delete()
val intent = Intent(context, LoginActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
}
}
response
})
}
okhttpClient.addInterceptor(Interceptor { chain: Interceptor.Chain ->
val builder1 = chain.request().newBuilder()
var request: Request? = null
if (!token.isEmpty()) {
builder1.addHeader("auth_key", "" + token)
}
if (!user_id.isEmpty()) {
builder1.addHeader("user_id", "" + user_id)
}
request = builder1.build()
chain.proceed(request)
})
return okhttpClient.build()
}
@Provides
fun providesGSONConvertorFactory(): Converter.Factory {
return GsonConverterFactory.create()
}
@Provides
fun providesRetrofit(baseUrl: String, convertor: Converter.Factory, okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder().baseUrl(baseUrl).addConverterFactory(convertor).client(okHttpClient).build()
}
@Provides
fun providesApiService(retrofit: Retrofit): ApiService {
return retrofit.create(ApiService::class.java)
}
}
在 hilt-dagger 中创建了一次单例实例,但令牌和 user_id 将在登录后可用。登录后我需要新的 okhttpclient。我在没有 DI 的情况下做到了。但是不知道如何处理 hilt-dagger.
更好的方法是让您的 API 服务方法为需要令牌的 API 注释 @Headers("Token-required")
。然后在您的拦截器方法中检查此 header 为:
if (request.header("Token-required") != null) {
request = request.newBuilder()
.addHeader("token", "your token value")
.build()
}