У меня есть проект с несколькими модулями в Android Studio. Модуль может иметь зависимость от другого модуля, например:Многомодульная обработка аннотаций в Android Studio
Модуля PhoneApp -> Модуля FeatureOne -> Модуль услуги
Я включил мою обработку аннотаций в корневом модуле, но происходит андроид-склонные обработки аннотаций только на самом верхнем уровне (PhoneApp), чтобы теоретически иметь доступ ко всем модулям во время компиляции. Однако то, что я вижу в сгенерированном java-файле, это только классы, аннотированные в PhoneApp, и ни один из других модулей.
PhoneApp/build/generated/source/apt/debug/.../GeneratedClass.java
В других модулях, я найти сгенерированный файл в каталоге промежуточных, который содержит только аннотированные файлы из этого модуля.
FeatureOne/build/intermediates/classes/debug/.../GeneratedClass.class
FeatureOne/build/intermediates/classes/debug/.../GeneratedClass.java
Моя цель состоит в том, чтобы иметь один сгенерированный файл в PhoneApp, что позволяет мне получить доступ к аннотированным файлам из всех модулей. Не совсем понятно, почему процесс генерации кода работает для каждого и не может заполнить все аннотации в PhoneApp. Любая помощь оценивается.
код довольно простой и прямой вперед до тех пор, checkIsValid() опущена, как она работает правильно:
Аннотация Процессор:
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
try {
for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(GuiceModule.class)) {
if (checkIsValid(annotatedElement)) {
AnnotatedClass annotatedClass = new AnnotatedClass((TypeElement) annotatedElement);
if (!annotatedClasses.containsKey(annotatedClass.getSimpleTypeName())) {
annotatedClasses.put(annotatedClass.getSimpleTypeName(), annotatedClass);
}
}
}
if (roundEnv.processingOver()) {
generateCode();
}
} catch (ProcessingException e) {
error(e.getElement(), e.getMessage());
} catch (IOException e) {
error(null, e.getMessage());
}
return true;
}
private void generateCode() throws IOException {
PackageElement packageElement = elementUtils.getPackageElement(getClass().getPackage().getName());
String packageName = packageElement.isUnnamed() ? null : packageElement.getQualifiedName().toString();
ClassName moduleClass = ClassName.get("com.google.inject", "Module");
ClassName contextClass = ClassName.get("android.content", "Context");
TypeName arrayOfModules = ArrayTypeName.of(moduleClass);
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("juice")
.addParameter(contextClass, "context")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(arrayOfModules);
methodBuilder.addStatement("$T<$T> collection = new $T<>()", List.class, moduleClass, ArrayList.class);
for (String key : annotatedClasses.keySet()) {
AnnotatedClass annotatedClass = annotatedClasses.get(key);
ClassName className = ClassName.get(annotatedClass.getElement().getEnclosingElement().toString(),
annotatedClass.getElement().getSimpleName().toString());
if (annotatedClass.isContextRequired()) {
methodBuilder.addStatement("collection.add(new $T(context))", className);
} else {
methodBuilder.addStatement("collection.add(new $T())", className);
}
}
methodBuilder.addStatement("return collection.toArray(new $T[collection.size()])", moduleClass);
TypeSpec classTypeSpec = TypeSpec.classBuilder("FreshlySqueezed")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(methodBuilder.build())
.build();
JavaFile.builder(packageName, classTypeSpec)
.build()
.writeTo(filer);
}
Это просто для демонстрации обработки аннотаций, который работает с Guice , если кому-то интересно.
Итак, как я могу получить все аннотированные классы, которые будут включены в сгенерированный файл PhoneApp .java из всех модулей?
Это хороший вопрос.Я думаю, что многие люди оценят, если вы поделитесь своим решением, когда найдете его, я еще этого не сделал. В разделе [dbFlow project issues] (https://github.com/Raizlabs/DBFlow/issues/266) обсуждается ограничение процессора, что можно считать доказательством того, что невозможно реализовать требуемые кросс- процессор аннотации модуля. – konata
Поскольку процессор аннотации работает для каждого модуля отдельно, вы можете попробовать инкрементный подход, но это немного зависит от вашего случая. Он может работать, если вам не нужно изменять весь класс после обработки следующего модуля, но добавлять только новые строки в существующий класс: 1. При обработке первого модуля сгенерируйте свой класс в указанном месте (где-то в модуле PhonApp ** сгенерированное ** дерево); 2. При обработке следующего модуля проверьте, существует ли сгенерированный класс и добавьте в него новый код. – konata
Поскольку это была просто демонстрация в презентации, я больше не искал решения. (Думал, что возник вопрос о том, почему сгенерированный файл не включал все данные модулей) Я действительно рассматривал использование задач Gradle для копирования сгенерированных файлов из каждого модуля, но предпочел бы решение, которое не нужно было бы полагаться на инструменты сборки , – fakataha