Android Dagger2 + OkHttp +带有拦截器的改型(用于刷新令牌)依赖周期错误

时间:2019-05-08 22:55:39

标签: android retrofit dagger-2 interceptor okhttp

我遇到了依赖周期错误的“典型”问题,试图调用一个拦截器中的刷新令牌。我找到了一些相关的问题和答案,特别是这个one和这个one。我跟随他们,并进行了代码编译。

但是它不起作用,因为“ 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'中始终为null:

val authService = authServiceHolder.get()

我有两个实例,一个用于旧版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,
        (...) {

使用此代码,我在'TokenExpiredInterceptor'中有一个'AuthServiceHolder'实例,它不为null,但为空。 我在上面的链接中看到,我必须使用以下内容重构“ 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
    }`

但是我不知道放在哪里。我已经在'MyMicroservicesApiModule'的'AuthTokenBindingsModule'中尝试过,但没有成功,它始终为空。

为了简化程序和保护隐私,我省略了几行代码。

有什么主意吗?预先感谢。

0 个答案:

没有答案