Dagger 2 无法访问 Retrofit

Posted

技术标签:

【中文标题】Dagger 2 无法访问 Retrofit【英文标题】:Dagger 2 cannot access Retrofit 【发布时间】:2018-04-17 21:50:42 【问题描述】:

我正在尝试使用 Dagger 2(带有 android 模块)向我的存储库提供一个 Retrofit 实例。购买我遇到了错误:

错误:无法访问改造

像毕加索这样的其他实例被成功注入,我只是在改造方面遇到了问题。

我的模块

@Module
class NetworkModule 

@Provides
@Singleton
fun providesRetrofit(): Retrofit 
    return Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl(URL_BASE)
            .build()


@Provides
@Singleton
fun providesPicasso(context: Context): Picasso 
    return Picasso.Builder(context)
            .loggingEnabled(true)
            .build()


@Provides
@Singleton
fun providesRemoteRepository(retrofit: Retrofit): RemoteRepository = RemoteRepository(retrofit)

@Provides
@Singleton
fun providesRepository(remote: RemoteRepository): Repository = RepositoryImp(remote)


我的应用程序组件

@Singleton
@Component(modules = arrayOf(
        AppModule::class, NetworkModule::class, AndroidInjectionModule::class, ActivityBuilder::class
))
interface AppComponent 

    @Component.Builder
    interface Builder 

        @BindsInstance
        fun application(app: Application): Builder

        fun build(): AppComponent

    

    fun inject(application: AppApplication)


应用组件

@Module
class AppModule 

    @Provides
    @Singleton
    fun providesApplicationContext(app: Application): Context = app


活动生成器

@Module
abstract class ActivityBuilder 

    @ContributesAndroidInjector(modules = arrayOf(MainActivityModule::class))
    abstract fun bindMainActivity(): MainActivity


我的仓库'

class RepositoryImp @Inject constructor(val remoteRepository: RemoteRepository) : Repository 

    override fun fetchData() 

    


我的远程仓库

class RemoteRepository @Inject constructor(retrofit: Retrofit) 

    val service: ApiService

    init 
        service = retrofit.create(ApiService::class.java)
    


Gradle 日志

e: error: cannot access Retrofit
e: 

e:   class file for retrofit2.Retrofit not found
e:   Consult the following stack trace for details.
e:   com.sun.tools.javac.code.Symbol$CompletionFailure: class file for retrofit2.Retrofit not found

w: warning: Supported source version 'RELEASE_7' from annotation processor 'android.arch.lifecycle.LifecycleProcessor' less than -source '1.8'
w: 


e: java.lang.IllegalStateException: failed to analyze: org.jetbrains.kotlin.kapt3.diagnostic.KaptError: Error while annotation processing
    at org.jetbrains.kotlin.analyzer.AnalysisResult.throwIfError(AnalysisResult.kt:57)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules(KotlinToJVMBytecodeCompiler.kt:138)
    at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:154)
    at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:58)
    at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:103)
    at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:51)
    at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:92)
    at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$2.invoke(CompileServiceImpl.kt:386)
    at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$2.invoke(CompileServiceImpl.kt:96)
    at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:889)
    at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:96)
    at org.jetbrains.kotlin.daemon.common.DummyProfiler.withMeasure(PerfUtils.kt:137)
    at org.jetbrains.kotlin.daemon.CompileServiceImpl.checkedCompile(CompileServiceImpl.kt:916)
    at org.jetbrains.kotlin.daemon.CompileServiceImpl.doCompile(CompileServiceImpl.kt:888)
    at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:385)
    at sun.reflect.GeneratedMethodAccessor86.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.jetbrains.kotlin.kapt3.diagnostic.KaptError: Error while annotation processing
    at org.jetbrains.kotlin.kapt3.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:90)
    at org.jetbrains.kotlin.kapt3.AnnotationProcessingKt.doAnnotationProcessing$default(annotationProcessing.kt:42)
    at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.runAnnotationProcessing(Kapt3Extension.kt:205)
    at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.analysisCompleted(Kapt3Extension.kt:166)
    at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.analysisCompleted(Kapt3Extension.kt:82)
    at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM$analyzeFilesWithJavaIntegration$2.invoke(TopDownAnalyzerFacadeForJVM.kt:96)
    at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:106)
    at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:83)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:377)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:68)
    at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:96)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:368)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules(KotlinToJVMBytecodeCompiler.kt:133)
    ... 29 more


:app:kaptDebugKotlin FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:kaptDebugKotlin'.
> Internal compiler error. See log for more details

谢谢!

【问题讨论】:

【参考方案1】:

我发现了问题,在 build.gradle ... 我的改造实例在一个单独的模块中。这个模块是一个api:

应用构建.gradle

api project(':data')

我在改造依赖项中使用了实现。我改成api,问题就解决了。

api "com.squareup.retrofit2:retrofit:$retrofit_version"
api "com.squareup.retrofit2:converter-gson:$retrofit_version"

【讨论】:

先生,您拯救了我的一天! 使用 api 公开其他层不需要的库不是一个坏习惯吗? 这似乎是一个知道Dagger issue,另一种方法也可以在主模块中实现Retrofit。 不与 Retrofit 交互的模块应该对此一无所知。【参考方案2】:

接受的答案有效,但使用api 函数会将data 模块使用的所有其他库暴露给app 模块。为避免这种情况,只需将改造依赖项添加到您的应用模块或您需要依赖项的任何地方。

implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"

上面是app 模块的Gradle 文件。如果您的 Retrofit 实例还具有其他依赖项,例如 RxJava2CallAdapterFactory,请不要忘记添加这些依赖项。

【讨论】:

【参考方案3】:

如果您不想在 appModule 中包含改造依赖项,则应创建一个包含改造实例的新类:

@Singleton
class RetrofitContainer  

    val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    companion object 
        private const val BASE_URL = "https://jsonplaceholder.typicode.com"
    

然后,在你的 dagger 模块中添加以下依赖项:

@Module
@InstallIn(SingletonComponent::class)
object NetworkingModule 

    @Singleton
    @Provides
    fun provideRetrofit(): RetrofitContainer = RetrofitContainer()

    @Singleton
    @Provides
    fun providePhotoApi(
        retrofitContainer: RetrofitContainer
    ): PhotoApi 
        return retrofitContainer.retrofit.create(PhotoApi::class.java)
    

【讨论】:

以上是关于Dagger 2 无法访问 Retrofit的主要内容,如果未能解决你的问题,请参考以下文章

Android Annotations生成类,但dagger2 @Module类无法访问这些类

无法提供匕首改装

MVP+Retrofit+RxJava+Dagger框架

MVP+Retrofit+RxJava+Dagger框架

Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava

Dagger2:无法在 WorkManager 中注入依赖项