Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/206.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Dagger找不到由其他批注处理器生成的类_Java_Android_Dagger 2_Annotation Processing_Annotation Processor - Fatal编程技术网

Java Dagger找不到由其他批注处理器生成的类

Java Dagger找不到由其他批注处理器生成的类,java,android,dagger-2,annotation-processing,annotation-processor,Java,Android,Dagger 2,Annotation Processing,Annotation Processor,我已经编写了一个简单的注释处理器(只是为了好玩),它将生成我在上一个项目中编写的一些样板代码。它实际上通过收集活动类的注释来生成如下模块 @Module abstract class ActivityInjectorModule { @ContributesAndroidInjector abstract fun providesMain2Activity(): Main2Activity @ContributesAndroidInjector abstract fun pro

我已经编写了一个简单的注释处理器(只是为了好玩),它将生成我在上一个项目中编写的一些样板代码。它实际上通过收集活动类的注释来生成如下模块

@Module
abstract class ActivityInjectorModule {
  @ContributesAndroidInjector
  abstract fun providesMain2Activity(): Main2Activity

  @ContributesAndroidInjector
  abstract fun providesMainActivity(): MainActivity
}
然而,当我使用dagger运行它时,dagger似乎找不到由注释处理器生成的类。虽然,类是生成的并存在于生成的目录中,但我可以在源代码中使用它,但在编译时,dagger生成以下异常。有专家建议吗

error: cannot find symbol
@dagger.Component(modules = {dagger.android.AndroidInjectionModule.class, com.mallaudin.daggietest.di.AppModule.class, ActivityInjectorModule.class})
                                                                                                                       ^
  symbol: class ActivityInjectorModule
这是主要的应用程序组件

@Singleton
@Component(
    modules = [
        AndroidInjectionModule::class,
        AppModule::class,
        ActivityInjectorModule::class
    ]
)
interface AppComponent : AndroidInjector<App> {


    @Component.Builder
    interface Builder {

        fun addContext(@BindsInstance ctx: Context): Builder

        fun build(): AppComponent
    }
}
@Singleton
@组成部分(
模块=[
AndroidInjectionModule::类,
AppModule::类,
ActivityInjectorModule::类
]
)
接口组件:AndroidJector

您可以看到生成的文件在同一个包中,但也引用了完全限定名。仍然匕首报告错误


如果有人想试验,这里是github存储库

可能有一种更优雅的方法来解决这个问题,但最简单、最可靠的解决方案是使用
javac
执行两次操作-一次只运行注释处理器,第二次执行它通常执行的所有操作

javac
指定了两个可以帮助您解决问题的选项

-proc:{none,only}

控制是否完成批注处理和/或编译-proc:none表示编译在没有注释处理的情况下进行-proc:only表示只进行注释处理,不进行任何后续编译

-处理器类别1[,类别2,类别3…]

要运行的批注处理器的名称。这将绕过默认的发现过程

第一步(仅运行您自己的注释处理器)是

第二步(常规构建)是

如果您使用的是Ant或Maven之类的工具,那么您应该能够更新构建指令,使其具有两个编译器过程,并且只需付出最小的努力

编辑:下面是我对Gradle指令的尝试

我对Gradle没有经验,但看起来你需要这样做

在Gradle构建脚本中,需要定义预处理任务,并将对任务的依赖项添加到javaCompile任务中

javaCompile.dependsOn myAnnotationTask

task myAnnotationTask(type: JavaCompile) {
    options.compilerArgs << '-proc:only' << '-processors com.foo.bar.MyAnnotationProcessor'
}
javaCompile.dependsOn myAnnotationTask
任务myAnnotationTask(类型:JavaCompile){

options.compilerArgs新答案 不知何故,我没有注意到您正在使用kapt。如果您将其添加到构建中,kapt可以处理您的类,即使没有完整的限定名(这很了不起)。gradle:

kapt {
    arguments {
        arg("argumentIncremental", 'true')
    }

    correctErrorTypes = true

}
更多信息:


前面的答案可能有用,因为有人在gradle中与annotationProcessor(apt)有相同的问题

简短回答:为ActivityInjectorModule使用完全限定名称:

@dagger.Component(modules = {dagger.android.AndroidInjectionModule.class, com.mallaudin.daggietest.di.AppModule.class, com.mallaudin.daggietest.di.ActivityInjectorModule.class})
或者将两个文件放在同一个包中

长答案:Dagger是一个注释处理器,它在编译代码之前运行,并且(可能)在其他注释处理器运行之前运行。处理器运行的顺序没有定义


Dagger annotation processor将处理用@Dagger.Component注释的TypeElement,并尝试查找包括“ActivityInjectorModule.class”在内的所有模块。问题是,ActivityInjectorModule可能尚未生成。因此,“ActivityInjectorModule”此时将没有包。Dagger将假定ActivityInjectorModule与组件类驻留在同一个包中,并且不会添加导入。通常的解决方法是为生成的类使用全名,如果其他批注处理器使用这些类。有时移动批注进程是有意义的向差异渐变模块唱歌,但我不认为这是您想要的。

解决方案:

  • 生成java代码。
    Kapt
  • 在尽可能早的一轮中写入生成的文件
  • 说明:

    Javac
    annotation processor使用轮而不是定义处理器顺序。因此,通常简化算法如下:

  • 收集所有java源代码
  • 运行所有批注处理器。任何批注处理器都可以使用生成新文件
  • 收集所有生成的文件,如果有,再次运行步骤2
  • 如果没有生成文件,则再运行一轮,返回
    true
    ,表示这是最后一轮
  • 现在有一点关于
    kapt
    kapt
    来运行注释处理器。为了使之成为可能,它首先运行kotlin compliler并在它们上运行
    javac
    。目前
    kapt
    ,这意味着它不会为注释处理器生成的kotlin类生成java存根。 注意:
    javac
    仍然使用多轮,它无法获取生成的kotlin源。

    回到你的问题上来,一个可能的选择是将生成的类移动到一个单独的模块中,就像

    但最简单的选择是直接生成java代码,生成的java类将由
    javac
    自动获取,启动第二轮注释处理,dagger将在其中处理它们

    再多说几句:

    • 不要在
      RoundEnvironment.processingOver()==true
      时生成代码,它不会触发另一轮。在看到注释的同一轮中生成代码
    • 要使生成的代码对注释处理器可见,请使用编写它

    你能分享你的应用程序类或者你定义所有模块的地方吗?@ShwetaChauhan我已经更新了代码。请看一看。应用程序类扩展DaggerApplication()对吗?我已经在做了。实际上我已经搜索了很多关于这个的信息
    javaCompile.dependsOn myAnnotationTask
    
    task myAnnotationTask(type: JavaCompile) {
        options.compilerArgs << '-proc:only' << '-processors com.foo.bar.MyAnnotationProcessor'
    }
    
    kapt {
        arguments {
            arg("argumentIncremental", 'true')
        }
    
        correctErrorTypes = true
    
    }
    
    @dagger.Component(modules = {dagger.android.AndroidInjectionModule.class, com.mallaudin.daggietest.di.AppModule.class, com.mallaudin.daggietest.di.ActivityInjectorModule.class})