重新初始化Dagger 2提供的对象

问题描述 投票:0回答:1

我有一个名为LoginService的接口,可与Retrofit一起使用。用户登录之前没有accessToken。用户登录后,应使用acessToken更新LoginService实例,以便用户可以从应用程序注销。问题是,即使未将LoginService类声明为@Singleton,也不会更新。如果用户关闭了该应用程序并再次将其重新打开,则LoginService已更新,因此他可以注销该应用程序。 accessToken更新后,如何重新初始化LoginService实例?

android dagger-2 dagger
1个回答
0
投票

这里的关键不是重新初始化实例,而是在用户登录时创建单独的服务。

您需要有两个不同的接口,一个用于API的预登录,另一个用于后登录。

所以一个将是Authapi.kt,另一个将是Api.kt

所以首先我们需要为每个服务创建OkHttpBuilder,

 @Provides
    @Singleton
    @Named(NetModule.NO_AUTH_CLIENT)
    fun provideNoAuthOkHttpClient(
            okHttpClientBuilder: OkHttpClient.Builder
    ): OkHttpClient {
        return okHttpClientBuilder.build()
    }

    @Provides
    @Singleton
    @Named(NetModule.AUTH_CLIENT)
    fun provideAuthOkHttpClient(
            okHttpClientBuilder: OkHttpClient.Builder,
            tokenInterceptor: NetworkInterceptor
    ): OkHttpClient {
        return okHttpClientBuilder.addInterceptor(tokenInterceptor).build()
    }

网络拦截器是您更新API的访问令牌的类。

NetworkInterceptor.kt

class NetworkInterceptor @Inject constructor(
        val context: Context,
        serverBaseUrl: String,
        val moshi: Moshi,
        val preferences: PreferenceUtility

) : Interceptor {


    private fun Request.Builder.setDefaultHeaders(): Request.Builder {
        addHeader("App_version_code", BuildConfig.VERSION_CODE.toString())
        addHeader("App_version_name", BuildConfig.VERSION_NAME)
        addHeader("Mobile_model", Build.MODEL.toString())
        addHeader("OS_version", Build.VERSION.SDK_INT.toString())
        addHeader("OS_version_release", Build.VERSION.RELEASE.toString())
        if (preferences.customerId != -1L)
            addHeader("Client_id", preferences.customerId.toString())
        return this
    }

    private fun makeRequestWithAuthTokenAndTimeStamp(request: Request) = request.newBuilder()
            .setDefaultHeaders()
            .apply {
                val oldHeader = request.header("Authorization")
                if (oldHeader.isNullOrBlank()) {
                    val token = if (preferences.authToken.isBlank() || !preferences.customerAuthenticated) BuildConfig.ANONYMOUS_TOKEN else preferences.authToken
                    addHeader("Authorization", "Bearer $token")
                }
            }
            .url(request.url())
            .method(request.method(), request.body())
            .build()

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
         // ADD THE TOKEN'S OVER HERE
        var response = 
           chain.proceed(makeRequestWithAuthTokenAndTimeStamp(request))
         //You can also add refersh logic here.
        return response
    }

}

您的NetworkModule.kt将为

@Provides
    @Singleton
    @Named(NetModule.NO_AUTH_CLIENT)
    fun provideNoAuthInterceptorRetrofit(
            moshi: Moshi,
            @Named(NetModule.NO_AUTH_CLIENT) okHttpClient: OkHttpClient,
            debugPreferenceUtility: DebugPreferenceUtility
    ): Retrofit {
        return Retrofit.Builder()
                .addConverterFactory(MoshiConverterFactory.create(moshi))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(debugPreferenceUtility.serverBaseUrl)
                .client(okHttpClient)
                .build()
    }

    @Provides
    @Singleton
    @Named(NetModule.AUTH_CLIENT)
    fun provideAuthInterceptorRetrofit(
            moshi: Moshi,
            @Named(NetModule.AUTH_CLIENT) okHttpClient: OkHttpClient,
            debugPreferenceUtility: DebugPreferenceUtility
    ): Retrofit {
        return Retrofit.Builder()
                .addConverterFactory(MoshiConverterFactory.create(moshi))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(debugPreferenceUtility.serverBaseUrl)
                .client(okHttpClient)
                .build()
    }


    @Provides
    @Singleton
    fun provideApi(@Named(AUTH_CLIENT) retrofit: Retrofit) = retrofit.create(Api::class.java)



    @Provides
    @Singleton
    fun provideAuthApi(@Named(NO_AUTH_CLIENT) retrofit: Retrofit) = retrofit.create(AuthApi::class.java)


因此将用于预登录的API将放置在AuthApi.kt内例如发送OTP等,其余所有API都将放置在Api.kt内,网络拦截器将负责添加令牌。

© www.soinside.com 2019 - 2024. All rights reserved.