java - Dagger 找不到其他注释处理器生成的类

标签 java android dagger-2 annotation-processing annotation-processor

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

@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
    }
}

ActivityInjectorModule类由注解处理器生成,存在于生成的目录中。

应用类

class App : DaggerApplication() {
    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder().addContext(this).build()
    }
}

Everything works perfectly, if I create the generated class myself. Somehow on compile time, dagger is unable to find the class when generated by my annotation processor.

在 Yuriy Kulikov 的回答之后,

yurily's answer

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

这是link如果有人想实验,可以到 github 存储库

最佳答案

解决方案:

  1. 生成java代码。 Kapt does not support multiple rounds .
  2. 尽早编写生成的文件。

解释:

Javac 注释处理器使用循环而不是定义处理器顺序。所以通常简化的算法是这样的:

  1. 收集所有 java 资源
  2. 运行所有注释处理器。任何注释处理器都可以使用 Filer 生成新文件.
  3. 收集所有生成的文件,如果有,再次运行第 2 步。
  4. 如果没有生成文件,再运行一轮 RoundEnvironment.processingOver()返回 true,表示这是最后一轮。

Here is a pretty good explanation of the process

现在谈谈kaptKapt uses javac运行注释处理器。为了使其成为可能,它首先运行 kotlin compliler 到 generate java stub files并对它们运行 javac。当前 kapt does not support multiple rounds ,这意味着它不会为注释处理器生成的 kotlin 类生成 java stub 。 注意:javac 仍然使用多轮,只是无法获取生成的 kotlin 源。

所以,回到你的问题。一种可能的选择是将生成的类移动到一个单独的模块中,例如 described here。 .

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

再补充几点:

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

关于java - Dagger 找不到其他注释处理器生成的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57235136/

相关文章:

java - 选择文件夹 Intent 并在 Intent 完成时进行锻炼?

Android - 填充不随图层列表中的状态而改变

android - 通过模块与注入(inject)构造函数进行 Dagger 2 配置

java - 如何在 Java Junit 中测试异常

java - 以编程方式设置 jsoup 解析的网页的值

java - 在 Android 中使用 Apache POI 时的兼容性问题

android - 如何使用 dagger2 注入(inject)没有任何 Activity 或 fragment 的 java 类

android - Kotlin + Dagger - 为 ViewModel 工厂注入(inject) Map

java - Applet 组件不可见

java - 我们是否需要将接口(interface)方法声明为抽象的