为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

江户川乱折腾 2023-04-26 14:46:19
我已经编写了一个简单的 Annotation Processor(只是为了好玩),它将生成一些我在之前的项目中编写的样板代码。它实际上通过收集 Activity 类上的注解来生成如下所示的模块@Moduleabstract class ActivityInjectorModule {  @ContributesAndroidInjector  abstract fun providesMain2Activity(): Main2Activity  @ContributesAndroidInjector  abstract fun providesMainActivity(): MainActivity}但是,当我用匕首运行它时,匕首似乎无法找到我的注释处理器生成的类。虽然类已生成并存在于生成的目录中,但我可以在我的源代码中使用它,但在编译时,匕首会产生以下异常。有专家建议吗?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()    }}如果我自己创建生成的类,一切都很完美。不知何故在编译时,匕首无法找到我的注释处理器生成的类。在 Yuriy Kulikov 的回答之后,您可以看到生成的文件在同一个包中,但也使用完全限定名称进行引用。还是dagger报错。如果有人想试验,这里是github 存储库的链接
查看完整描述

3 回答

?
拉丁的传说

TA贡献1789条经验 获得超8个赞

解决方案:

  1. 生成java代码。Kapt 不支持多轮。

  2. 在尽可能早的一轮写入生成的文件。

解释:

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

  1. 收集所有 java 资源

  2. 运行所有注释处理器。任何注释处理器都可以使用Filer生成新文件。

  3. 收集所有生成的文件,如果有,请再次运行步骤 2。

  4. 如果没有生成文件,则再运行一轮RoundEnvironment.processingOver()返回true,表示这是最后一轮。

这是对这个过程的一个很好的解释

现在有点关于kaptKapt 使用 javac运行注解处理器。为了使其成为可能,它首先运行 kotlin compliler 以生成 java 存根文件并javac在其上运行。目前kapt 不支持多轮,这意味着它不会为注释处理器生成的 kotlin 类生成 java 存根。 注意:javac仍然使用多轮,只是无法获取生成的 kotlin 源代码。

那么,回到你的问题。一种可能的选择是将您生成的类移动到一个单独的模块中

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

再补充几点:

  • 不要在 时生成您的代码RoundEnvironment.processingOver() == true,它不会触发另一轮。在您看到注释的同一轮中生成它。

  • 要使生成的代码对注释处理器可见,请使用Filer编写它。


查看完整回答
反对 回复 2023-04-26
?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

新答案 我以某种方式错过了您正在使用 kapt。Kapt 可以处理你的类,即使没有完整的限定名(这很了不起),如果你将它添加到你的 build.gradle 中:


kapt {

    arguments {

        arg("argumentIncremental", 'true')

    }


    correctErrorTypes = true


}

有关此的更多信息:https ://kotlinlang.org/docs/reference/kapt.html#non-existent-type-correction


以前的答案可能很有用,有人对 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 注释处理器将处理用 @dagger.Component 注释的 TypeElement,它会尝试找到所有模块,包括“ActivityInjectorModule.class”。问题是,ActivityInjectorModule 可能还没有生成。因此“ActivityInjectorModule”此时不会有包。Dagger 将假定 ActivityInjectorModule 与 Component 类位于同一个包中,并且不会添加导入。通常的解决方法是为生成的类使用完全限定名称,如果它们被其他注释处理器使用的话。有时将注释处理移动到不同的 gradle 模块是有意义的,但我不认为这是你想要的。


查看完整回答
反对 回复 2023-04-26
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

可能有更优雅的方法来解决这个问题,但最简单和最可靠的解决方案是执行两次传递 — 一次javac仅运行注释处理器,第二次执行它通常执行的所有操作。


该javac 文档指定了两个可以帮助您的选项。


-proc:{无,仅}


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


-处理器类 1 [,类 2,类 3 ...]


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


第一步(只运行你自己的注解处理器)是


javac -proc:only -processor com.foo.bar.MyProcessor MyProject/src/*

第二遍(常规构建)是


javac MyProject/src/*

如果您使用的是 Ant 或 Maven 之类的东西,您应该能够更新构建指令,只需最少的工作量即可获得两次编译器传递。


编辑:这是我对 Gradle 说明的尝试


我没有使用 Gradle 的经验,但看起来你需要做这样的事情。


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


javaCompile.dependsOn myAnnotationTask


task myAnnotationTask(type: JavaCompile) {

    options.compilerArgs << '-proc:only' << '-processors com.foo.bar.MyAnnotationProcessor'

}


查看完整回答
反对 回复 2023-04-26
  • 3 回答
  • 0 关注
  • 124 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信