gre*_*nce 3 android kotlin dagger-2
Dagger无法识别Kotlin中提供的一种方法。这是模块的重要部分:
@Provides
@AppScope
fun provideClient(cache: Cache, interceptors: List<Interceptor>?): OkHttpClient {
val httpBuilder = OkHttpClient.Builder()
interceptors?.let {
for (interceptor in interceptors) {
httpBuilder.addInterceptor(interceptor)
}
}
return httpBuilder
.cache(cache)
.build()
}
@Provides
@AppScope
fun provideInterceptors(): List<Interceptor>? {
return listOf(HttpLoggingInterceptor().setLevel(WebServiceConfig.LOGGING_LEVEL))
}
Run Code Online (Sandbox Code Playgroud)
错误消息如下:
AppComponent.java:15: error: java.util.List<? extends okhttp3.Interceptor> cannot be provided without an @Provides-annotated method.
Run Code Online (Sandbox Code Playgroud)
如果我使用MutableList,则可以使用。因此,问题是:Dagger2 / Kotlin中的List有什么问题?
原来这是一个泛型互操作问题。
当您在Kotlin中将List接口的a(例如Interceptor)用作参数时,从Java的角度来看,您会认为它具有列表类型参数的通配符,因为它List是协变的:
OkHttpClient provideClient(List<? extends Interceptor> interceptors) { ... }
Run Code Online (Sandbox Code Playgroud)
但是,不会为返回类型添加此通配符。
List<Interceptor> provideInterceptors() { ... }
Run Code Online (Sandbox Code Playgroud)
您可以通过在Java文件中创建模块的实例,然后查看自动完成功能提供的方法来进行检查。
因此,问题在于Dagger在寻找List<? extends Interceptor>其他方法返回a的同时List<Interceptor>。
可能的解决方案:
使用@JvmSuppressWildCards注释可防止添加通配符(请参阅此处的相关问题)。从整个模块到您遇到问题的单个类型参数,它几乎可以在任何范围内使用:
interceptors: List<@JvmSuppressWildcards Interceptor>?
Run Code Online (Sandbox Code Playgroud)out在List您要在provideInterceptors方法中返回的上添加显式方差。有趣的是,当您从Java查看自动补全功能时,这不会显示出来,但是它可以修复构建。
fun provideInterceptors(): List<out Interceptor>? { ... }
Run Code Online (Sandbox Code Playgroud)使用MutableList您发现的界面没有此问题。
至于为什么只在使用a List而不是a 时发生这种情况MutableList:List仅在out位置上使用其type参数,因此它是协变的。这将导致为a List而不是为不变量生成通配符MutableList(这就是为什么可以正常工作的原因)。
另请注意,仅当type参数为非最终类型(开放类或接口)时,才会发生通配符生成。因此,您不会因为一个问题List<StringBuilder>(这是最终的)而遇到这个问题,但您会因为一个问题List<BufferedReader>(不是)而得到它
。
| 归档时间: |
|
| 查看次数: |
511 次 |
| 最近记录: |