我正在拥有一个包含2个模块的Android Studio项目:A和B.(我这里不包括Annotation Processor和Annotations模块)
B取决于A。
B是Android库模块,A是简单的Java库模块。我在模块B上也有一个注释处理器。
我面临的问题是:
我想根据放在两个模块 - A和B中的带注释文件生成一些代码。问题来自Annotation Processor的工作方式 - 只有源代码文件* .java - 没有编译* .class的。不幸的是,在编译B期间,Annotation Processor无法访问来自A ...
的源文件我唯一可以想到的是一种解决方案,即使是一种丑陋的解决方案,也包括带有来自模块A的带注释类的文件夹作为模块B的源集。这样我给模块B在编译期间访问这些文件。
sourceSets {
main {
java {
srcDirs = ['src/main/java', '../module_A/src/main/java/path/to/annotated/classes/folder']
}
}
}
解决了这个问题 - 现在Annotation Processor可以访问两个模块中的所有带注释的类,但是......
不幸的是,它引入了另一个问题......来自模块A的那些带注释的类现在被编译两次。它们包含在模块A的JAR文件和模块B的AAR文件中。
问题1:还有另一种方法可以从B上运行的注释处理器访问模块A的源文件吗? (从我能找到的,答案是否定的,但检查......)
问题2:如何从模块B的AAR最终包中排除那些已编译的文件(重复的文件)?
问题3:也许......这是绝对错误的做法?有什么建议吗?
提前致谢!
答案 0 :(得分:1)
Nop,仅使用java.lang.model
API无法达到您想要的效果。至少没有一些额外的技巧。
问题不在于binary-vs-source。注释处理器可以使用Elements#getTypeElement来内省编译的类以及源定义的类:
Elements elementUtil = processingEnvironment.getElementUtils();
TypeElement integerClass = elementUtil.getTypeElement("java.lang.Integer");
TypeElement myClass = elementUtil.getTypeElement("currently.compiled.Class");
但是你仍然需要在编译类路径上使用类来观察它,并且该类必须正在编译为getElementsAnnotatedWith
可见。
您可以使用FastClasspathScanner之类的工具解决以后的限制:它将使用它自己的机制在编译的字节码中查找注释,并将它们与编译过程分开报告给您。但是您无法解决类路径问题:如果您在编译类路径中没有某些依赖项,则无法处理它。所以你有一起编译模块 - 通过将它们合并为一个(如你所做的那样)或通过声明一个依赖于另一个模块。在以后的情况下,您可能无法使用getElementsAnnotatedWith
,但getTypeElement
和FastClasspathScanner将起作用。