У меня была «типичная» проблема ошибки цикла зависимости при попытке вызвать токен обновления в Interceptor. Я нашел несколько связанных вопросов и ответов, особенно этот один и этот один . Я последовал за ними, и он сделал код компиляции.
Но это не работает, потому что «ServiceHolder» всегда пуст (создается без службы), поэтому я думаю, что я делаю что-то не так с Dagger, и я не знаю, что.
У меня есть 'AuthServiceHolder':
class AuthServiceHolder {
internal var authService: AuthService? = null
fun get(): AuthService? {
return authService
}
fun set(authService: AuthService) {
this.authService = authService
}
}
У меня есть 'TokenExpiredInterceptor' (первые строки):
@TokenExpiredInterceptorScope
class TokenExpiredInterceptor @Inject constructor(private val authServiceHolder: AuthServiceHolder
) : Interceptor
Я пытаюсь заставить службу выполнить вызов, но в TokenExpiredInterceptor она всегда пуста:
val authService = authServiceHolder.get()
У меня есть 2 экземпляра retroft, один для устаревшего API, а другой для нового API. Общий модуль:
@Module
object CommonApiModule {
@JvmStatic
internal fun retrofitBuilder(okHttpClient: OkHttpClient, baseUrl: HttpUrl) = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
(...)
}
Модуль, в котором я создаю модификацию для нового API:
@Module
class MyMicroservicesApiModule(baseUrl: String) : BaseApiModule(baseUrl) {
@Provides
@ForNetworkApi(NetworkApiType.MY_MICROSERVICES)
@NetworkScope
internal fun retrofit(okHttpClient: OkHttpClient,
callAdapterFactory: RxJava2CallAdapterFactory,
moshi: Moshi): Retrofit =
CommonApiModule.retrofitBuilder(okHttpClient, httpUrl)
.addCallAdapterFactory(callAdapterFactory)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
}
Модуль с перехватчиком:
@Module(includes = [
(...)
])
abstract class AuthTokenBindingsModule {
@Binds
@IntoSet
@ForNetworkInterceptors
internal abstract fun tokenExpiredInterceptor(tokenExpiredInterceptor: TokenExpiredInterceptor): Interceptor
(...)
@Module
companion object {
(...)
@Provides
@JvmStatic
@NetworkScope
fun authServiceHolder(): AuthServiceHolder = AuthServiceHolder()
}
}
Модуль для создания httpClient:
@Module(includes = [HttpInterceptorsModule::class])
object HttpModule {
private const val CONNECTION_TIMEOUT = 25
private const val READ_CONNECTION_TIMEOUT = 25
private const val WRITE_CONNECTION_TIMEOUT = 25
private const val DISK_CACHE_SIZE: Long = 50 * 1024 * 1024
@JvmStatic
@Provides
@NetworkScope
internal fun httpClient(application: Application,
@ForNetworkInterceptors networkInterceptors: Set<@JvmSuppressWildcards Interceptor>,
@ForHttpInterceptors httpInterceptors: Set<@JvmSuppressWildcards Interceptor>): OkHttpClient {
val builder = httpClientBuilder(application)
httpInterceptors.forEach { it -> builder.addInterceptor(it) }
networkInterceptors.forEach { it -> builder.addNetworkInterceptor(it) }
if (BuildConfig.DEBUG) {
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
builder.addNetworkInterceptor(loggingInterceptor)
}
return builder.build()
}
@JvmStatic
private fun httpClientBuilder(application: Application): OkHttpClient.Builder {
val builder = OkHttpClient.Builder()
.connectTimeout(CONNECTION_TIMEOUT.toLong(), TimeUnit.SECONDS)
.readTimeout(READ_CONNECTION_TIMEOUT.toLong(), TimeUnit.SECONDS)
.writeTimeout(WRITE_CONNECTION_TIMEOUT.toLong(), TimeUnit.SECONDS)
val cacheDir = File(application.cacheDir, "http")
val cache = Cache(cacheDir, DISK_CACHE_SIZE)
builder.cache(cache)
return builder
}
}
Наконец, мой сетевой компонент:
@NetworkScope
@TokenExpiredInterceptorScope
@AuthenticatorScope
@Component(modules = [
(...)
CommonApiModule::class,
MyMicroservicesApiModule::class,
AuthTokenBindingsModule::class,
(...)
], dependencies = [AppServiceProvider::class])
interface NetworkComponent :
(...)
MyMicroservicesApiProvider,
(...) {
С этим кодом у меня есть экземпляр 'AuthServiceHolder' в 'TokenExpiredInterceptor', он НЕ является нулевым, но он пуст.
Я видел в ссылках выше, я должен реорганизовать поставщика 'AuthService' что-то вроде этого:
@Provides
@NetworkScope
internal fun authService(@ForNetworkApi(NetworkApiType.MY_MICROSERVICES) retrofit: Retrofit, authServiceHolder: AuthServiceHolder): AuthService {
val authService = retrofit.create(AuthService::class.java)
authServiceHolder.set(authService)
return authService
}`
Но я не знаю, где это поставить. Я пытался в AuthTokenBindingsModule, в MyMicroservicesApiModule, но безуспешно, он всегда пуст.
Я пропустил несколько строк кода, чтобы сделать его проще и для конфиденциальности.
Есть идеи? Заранее спасибо.