Mam projekt z wieloma modułami w Android Studio. Moduł może być zależnym od innego modułu, na przykład:Wielomodułowe przetwarzanie adnotacji w Android Studio
Module PhoneApp -> Moduł FeatureOne -> Module Usługi
podaję mój przetwarzania adnotacji w module głównym, ale android-apt przetwarzanie występuje adnotacja tylko na najwyższym poziomie (PhoneApp), aby teoretycznie miał dostęp do wszystkich modułów podczas kompilacji. Jednak w generowanym pliku java widzę tylko klasy opisane w PhoneApp i żadne z pozostałych modułów.
PhoneApp/build/generated/source/apt/debug/.../GeneratedClass.java
W innych modułach znajduję wygenerowany plik w katalogu półproduktów, który zawiera tylko adnotowane pliki z tego modułu.
Moim celem jest posiadanie pojedynczego wygenerowanego pliku w aplikacji PhoneApp, który umożliwia mi dostęp do plików z przypisami ze wszystkich modułów. Nie do końca wiadomo, dlaczego proces generowania kodu działa dla każdego i nie można zebrać wszystkich adnotacji w aplikacji PhoneApp. Każda pomoc doceniona.
Code jest dość proste i prosto do przodu tak daleko, checkIsValid() pomija się, jak to działa prawidłowo:
Adnotacja Procesor:
@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);
}
To właśnie na demo przetwarzania adnotacji, który współpracuje z Guice , jeśli ktoś jest ciekawy.
Jak mogę więc wszystkie klasy z adnotacjami dołączyć do wygenerowanego pliku .java PhoneApp ze wszystkich modułów?
to dobre pytanie.Myślę, że wiele osób doceni, jeśli podzielisz się swoim rozwiązaniem, gdy je znajdziesz, jeszcze nie. Istnieje dyskusja na temat ograniczeń procesorów w sekcji [dbFlow project issues section] (https://github.com/Raizlabs/DBFlow/issues/266), co można uznać za dowód na to, że niemożliwe jest wdrożenie pożądanego połączenia moduł adnotacji procesora. – konata
Ponieważ procesor adnotacji działa dla każdego modułu osobno, możesz spróbować podejścia przyrostowego, ale to trochę zależy od twojej sprawy. Może działać, jeśli nie trzeba zmieniać całej klasy po przetworzeniu następnego modułu, a jedynie dodawać nowe linie do istniejącej klasy: 1. Podczas przetwarzania pierwszego modułu należy wygenerować klasę w określonej lokalizacji (gdzieś w module modułu PhonApp ** wygenerowane ** drzewo); 2. Podczas przetwarzania następnego modułu sprawdź, czy wygenerowana klasa istnieje i dodaj do niego nowy kod. – konata
Ponieważ to była tylko prezentacja w prezentacji, nie kontynuowałem szukania rozwiązania. (Pomyślałem, że powstało pytanie, dlaczego wygenerowany plik nie zawiera wszystkich danych modułów) Rozważałem użycie zadań Gradle do skopiowania wygenerowanych plików z każdego modułu, ale wolałbym rozwiązanie, które nie musiałoby polegać na narzędziach do kompilacji . – fakataha