3 回答
TA贡献1789条经验 获得超8个赞
解决方案:
生成java代码。
Kapt
不支持多轮。在尽可能早的一轮写入生成的文件。
解释:
Javac
注释处理器使用回合而不是定义处理器顺序。所以通常简化的算法是这样的:
收集所有 java 资源
运行所有注释处理器。任何注释处理器都可以使用Filer生成新文件。
收集所有生成的文件,如果有,请再次运行步骤 2。
如果没有生成文件,则再运行一轮RoundEnvironment.processingOver()返回
true
,表示这是最后一轮。
这是对这个过程的一个很好的解释
现在有点关于kapt
。Kapt
使用 javac运行注解处理器。为了使其成为可能,它首先运行 kotlin compliler 以生成 java 存根文件并javac
在其上运行。目前kapt
不支持多轮,这意味着它不会为注释处理器生成的 kotlin 类生成 java 存根。 注意:javac
仍然使用多轮,只是无法获取生成的 kotlin 源代码。
那么,回到你的问题。一种可能的选择是将您生成的类移动到一个单独的模块中
但最简单的选择是直接生成 java 代码,你生成的 java 类将被自动拾取javac
,启动第二轮注释处理,dagger 将在其中处理它们。
再补充几点:
不要在 时生成您的代码
RoundEnvironment.processingOver() == true
,它不会触发另一轮。在您看到注释的同一轮中生成它。要使生成的代码对注释处理器可见,请使用Filer编写它。
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 模块是有意义的,但我不认为这是你想要的。
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'
}
添加回答
举报