Wah*_*han 6 android kotlin dagger retrofit dagger-hilt
我想使用拦截器刷新我的令牌,但我的拦截器需要 API 服务来进行 API 调用。我陷入了依赖循环。
这是我的 ApplicationModule 类:
@Module
@InstallIn(ApplicationComponent::class)
class ApplicationModule {
@Provides
fun providerBaseUrl() = AppConstants.BASE_URL
@Provides
@Singleton
fun provideOkHttpClient(authInterceptor: AuthInterceptor,
networkInterceptor: NetworkInterceptor) = if (BuildConfig.DEBUG) {
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
OkHttpClient.Builder()
.addInterceptor(authInterceptor)
.addInterceptor(loggingInterceptor)
.addInterceptor(networkInterceptor)
// .addInterceptor(refreshTokenInterceptor) // I want to put my interceptor here
.connectTimeout(2, TimeUnit.MINUTES)
.readTimeout(2, TimeUnit.MINUTES)
.writeTimeout(2, TimeUnit.MINUTES)
.build()
} else OkHttpClient
.Builder()
.connectTimeout(2, TimeUnit.MINUTES)
.readTimeout(2, TimeUnit.MINUTES)
.writeTimeout(2, TimeUnit.MINUTES)
.addInterceptor(authInterceptor)
.addInterceptor(networkInterceptor)
.build()
@Provides
@Singleton
fun provideRetrofit(
okHttpClient: OkHttpClient,
BASE_URL: String
): Retrofit =
Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create())
.baseUrl(BASE_URL)
.client(okHttpClient)
.build()
@Provides
@Singleton
fun provideApiService(retrofit: Retrofit): WebApi = retrofit.create(WebApi::class.java)
@Provides
@Singleton // this is my provider
fun provideRefreshTokenService(webApi: WebApi): RefreshTokenInterceptor {
return RefreshTokenInterceptor(webApi)
}
@Provides
fun provideAuthInterceptor(): AuthInterceptor {
return AuthInterceptor()
}
@Provides
fun provideNetWorkInterceptor(): NetworkInterceptor {
return NetworkInterceptor()
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的 RefreshTokenInterceptor:
class RefreshTokenInterceptor @Inject constructor(webApi: WebApi) : Interceptor {
var api = webApi
override fun intercept(chain: Interceptor.Chain): Response {
val requestBuilder = chain.request().newBuilder()
val updatedToken = getUpdatedToken(webApi = api)
requestBuilder.header("Authorization", updatedToken)
return chain.proceed(requestBuilder.build())
}
private fun getUpdatedToken(webApi: WebApi): String {
GlobalScope.launch {
val authTokenResponse = webApi.refreshToken()
val newToken = "${authTokenResponse.body()!!.data.token}"
SharedPref.getInstance(AppController.applicationContext()).setUserToken(newToken)
}
return SharedPref.getInstance(AppController.applicationContext()).getUserToken
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
我遇到了类似的问题并找到了解决方案。您可以使用 Lazy 接口将 api 实例包装在令牌拦截器中。这将解决您的循环依赖问题。
这是一个代码片段。
class RefreshTokenInterceptor @Inject constructor(private val webApi: Lazy<WebApi>) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val requestBuilder = chain.request().newBuilder()
val updatedToken = getUpdatedToken(webApi = api.get())
requestBuilder.header("Authorization", updatedToken)
return chain.proceed(requestBuilder.build())
}
private fun getUpdatedToken(webApi: WebApi): String {
GlobalScope.launch {
val authTokenResponse = webApi.refreshToken()
val newToken = "${authTokenResponse.body()!!.data.token}"
SharedPref.getInstance(AppController.applicationContext()).setUserToken(newToken)
}
return SharedPref.getInstance(AppController.applicationContext()).getUserToken
}
}
Run Code Online (Sandbox Code Playgroud)
小智 -1
看这个例子:
@Provides
@Singleton
fun provideDatabase(
@ApplicationContext context: Context,
@RoomCreateCallback callback: RoomDatabase.Callback
) = Room.databaseBuilder(context, TaskDatabase::class.java, Constants.TaskKeys.TASK_DATABASE)
.fallbackToDestructiveMigration()
.addCallback(callback)
.build()
@Provides
fun provideTaskDao(taskDatabase: TaskDatabase) = taskDatabase.taskDao()
@Provides
@Singleton
@RoomCreateCallback
fun provideDatabaseCreateCallback(
taskDatabase: Provider<TaskDatabase>,
@ApplicationScope applicationScope: CoroutineScope
) = object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
val dao = taskDatabase.get().taskDao()
applicationScope.launch {
dao.insert(Task("First task"))
dao.insert(Task("Second task"))
dao.insert(Task("Third task", important = true))
dao.insert(Task("Fourth task", completed = true))
dao.insert(Task("Fifth task"))
dao.insert(Task("Sixth task", completed = true))
dao.insert(Task("Seventh task"))
dao.insert(Task("Eighth task"))
}
}
}
Run Code Online (Sandbox Code Playgroud)
创建 RoomDatabase 时需要 RoomDatabase.Callback,但执行此回调时也需要 RoomDatabase。在 ProvideDatabaseCreateCallback() 函数中,我将 RoomDatabase 包装在 Provider<> 内。
| 归档时间: |
|
| 查看次数: |
2630 次 |
| 最近记录: |