Java 在添加拦截器并使用Dagger2注入拦截器后,改装服务始终为空
我有这样的重新登录改造服务Java 在添加拦截器并使用Dagger2注入拦截器后,改装服务始终为空,java,android,retrofit,dagger-2,okhttp,Java,Android,Retrofit,Dagger 2,Okhttp,我有这样的重新登录改造服务 interface TokenService { @GET("re-login") fun relogin(): Call<ReloginResponse> } @Module class NetModule(baseUrl: String) { var baseUrl = baseUrl @Provides @Singleton fun provideGson(): Gson { val
interface TokenService {
@GET("re-login")
fun relogin(): Call<ReloginResponse>
}
@Module
class NetModule(baseUrl: String) {
var baseUrl = baseUrl
@Provides
@Singleton
fun provideGson(): Gson {
val gsonBuilder = GsonBuilder()
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
return gsonBuilder.create()
}
@Provides
@Singleton
fun provideOkhttp(tokenInterceptor: TokenInterceptor): OkHttpClient {
val logging = HttpLoggingInterceptor()
logging.setLevel(HttpLoggingInterceptor.Level.BODY)
val client = OkHttpClient.Builder()
// .authenticator(tokenAutheticator)
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.addInterceptor(logging)
.addInterceptor(tokenInterceptor)
.build()
return client
}
@Provides
@Singleton
fun provideRetrofit(gson: Gson, okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder().addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(baseUrl)
.client(okHttpClient)
.build()
}
@Provides
@Singleton
fun provideTokenHoler():TokenHolder{
return TokenHolder()
}
@Provides
@Singleton
fun provideTokenService(retrofit: Retrofit,tokenHolder: TokenHolder):TokenService{
val tokenService = retrofit.create(TokenService::class.java)
tokenHolder.tokenService = tokenService
return tokenService
}
}
class TokenHolder {
var tokenService:TokenService?=null
get() = field
set(value) {field=value}
}
然后,TokenHolder
类是这样的
interface TokenService {
@GET("re-login")
fun relogin(): Call<ReloginResponse>
}
@Module
class NetModule(baseUrl: String) {
var baseUrl = baseUrl
@Provides
@Singleton
fun provideGson(): Gson {
val gsonBuilder = GsonBuilder()
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
return gsonBuilder.create()
}
@Provides
@Singleton
fun provideOkhttp(tokenInterceptor: TokenInterceptor): OkHttpClient {
val logging = HttpLoggingInterceptor()
logging.setLevel(HttpLoggingInterceptor.Level.BODY)
val client = OkHttpClient.Builder()
// .authenticator(tokenAutheticator)
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.addInterceptor(logging)
.addInterceptor(tokenInterceptor)
.build()
return client
}
@Provides
@Singleton
fun provideRetrofit(gson: Gson, okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder().addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(baseUrl)
.client(okHttpClient)
.build()
}
@Provides
@Singleton
fun provideTokenHoler():TokenHolder{
return TokenHolder()
}
@Provides
@Singleton
fun provideTokenService(retrofit: Retrofit,tokenHolder: TokenHolder):TokenService{
val tokenService = retrofit.create(TokenService::class.java)
tokenHolder.tokenService = tokenService
return tokenService
}
}
class TokenHolder {
var tokenService:TokenService?=null
get() = field
set(value) {field=value}
}
这是TokenInterceptor
类,我在TokenService部分得到null
@Singleton
class TokenInterceptor @Inject constructor(private val tokenHolder: TokenHolder) :Interceptor{
var token:String=""
override fun intercept(chain: Interceptor.Chain): Response {
val original = chain.request()
val originalHttpUrl = original.url()
val url = originalHttpUrl.newBuilder()
.addQueryParameter("token", token)
.build()
// Request customization: add request headers
val requestBuilder = original.newBuilder()
.url(url)
val request = requestBuilder.build()
val response = chain.proceed(request)
if(response.code()==401){
val newToken = tokenHolder.tokenService?.relogin()?.execute()?.body()?.token
val url1 = originalHttpUrl.newBuilder()
.addQueryParameter("token", newToken)
.build()
println("########## new new token ########## "+newToken)//this is null
// Request customization: add request headers
val requestBuilder1 = original.newBuilder()
.url(url1)
val request1 = requestBuilder1.build()
val response1 = chain.proceed(request1)
return response1
}
return chain.proceed(request)
}
}
我试图在得到
401
响应后点击重新登录,但我总是得到TokenService
null。我应该如何提供依赖关系?任何帮助都将不胜感激。谢谢据我所知,TokenHolder
拥有TokenService
的空实例,因为无法将其传递到那里。您正在通过Dagger创建TokenService实例并将其传递给TokenHolder,但它与您在拦截器中获得的实例不同。你应该颠倒你的依赖关系。将模块方法更新为此,并告诉我它是否有效
@Provides
@Singleton
fun provideTokenHolder(service:TokenService): TokenHolder{
return TokenHolder(service)
}
@Provides
@Singleton
fun provideTokenService(retrofit: Retrofit): TokenService{
return retrofit.create(TokenService::class.java)
}
TokenService不应为null,因此您应该如下声明TokenHolder
class TokenHolder(val service: TokenService)
此外,还要打破依赖圈。您必须更改令牌侦听器声明
class TokenInterceptor @Inject constructor(private val tokenHolder: Lazy<TokenHolder>) : Interceptor
class-TokenInterceptor@Inject构造函数(私有val-tokenHolder:Lazy):拦截器
用匕首包裹TokenHolder.Lazy,它应该可以完成任务。据我所知,
TokenHolder
拥有TokenService
的空实例,因为无法将其传递到那里。您正在通过Dagger创建TokenService实例并将其传递给TokenHolder,但它与您在拦截器中获得的实例不同。你应该颠倒你的依赖关系。将模块方法更新为此,并告诉我它是否有效
@Provides
@Singleton
fun provideTokenHolder(service:TokenService): TokenHolder{
return TokenHolder(service)
}
@Provides
@Singleton
fun provideTokenService(retrofit: Retrofit): TokenService{
return retrofit.create(TokenService::class.java)
}
TokenService不应为null,因此您应该如下声明TokenHolder
class TokenHolder(val service: TokenService)
此外,还要打破依赖圈。您必须更改令牌侦听器声明
class TokenInterceptor @Inject constructor(private val tokenHolder: Lazy<TokenHolder>) : Interceptor
class-TokenInterceptor@Inject构造函数(私有val-tokenHolder:Lazy):拦截器
用匕首包裹TokenHolder.Lazy,它应该可以完成任务。
TokenService
应该是provideTokenHoler()
(而不是相反)的依赖项尝试返回响应
@Blackbelt那样我会得到循环依赖项错误如果你同时保留这两个,当然你会创建一个循环。但是您不需要,tokenHolder:tokenHolder
作为`provideTokenService,是吗?TokenService
应该是provideTokenHoler()
的依赖项(而不是相反)尝试returnresponse
@Blackbelt,这样我就得到了循环依赖错误。如果你同时保留这两个错误,当然你会创建一个循环。但您不需要,tokenHolder:tokenHolder
作为`providedokenservice'的依赖项,你知道吗?我得到了循环依赖错误,因为在那里注入了改型,然后在OKhttp中注入了拦截器。你可以附加stacktrace吗?改型2.改型在com.pkg.di.module.NetModule.provideTokenService(改型)中注入com.pkg.token.TokenService注入com.pkg.di.module.NetModule.provideTokenHolder(服务)com.pkg.token.TokenHolder注入com.pkg.utils.TokenInterceptor。(TokenHolder)com.pkg.utils.TokenInterceptor注入com.pkg.di.module.NetModule.provideOkhttp(TokenInterceptor)okhttp3.OkHttpClient被注入com.pkg.di.module.NetModule.provideRetrofit(…,OkHttpClient)翻新2.翻新是不可理解的我希望这是可以理解的你能告诉我TokenHolder的意义吗?注入TokenService不是更容易吗?我遇到了循环依赖错误,因为在那里注入了改型,然后在OKhttp中注入了拦截器。您可以附加stacktrace吗?改型2.Reformation注入到com.pkg.di.module.NetModule.provideTokenService(改型)com.pkg.token.TokenService注入com.pkg.di.module.NetModule.provideTokenHolder(服务)com.pkg.token.TokenHolder注入com.pkg.utils.TokenInterceptor。(TokenHolder)com.pkg.utils.TokenInterceptor注入com.pkg.di.module.NetModule.provideOkhttp(TokenInterceptor)okhttp3.OkHttpClient被注入com.pkg.di.module.NetModule.provideRetrofit(…,OkHttpClient)翻新2.翻新是不可理解的我希望这是可以理解的你能告诉我TokenHolder的意义吗?仅仅注入令牌服务而不是注入它不是更容易吗?