1

我在使用2個模塊一個Android Studio項目:A和B(不包括在這裏的標註處理和註釋模塊)的Android標註處理來自不同模塊的訪問註解的類

B依賴於甲

B是Android庫模塊,A是簡單的Java庫模塊。我還具有上模塊B.註釋處理器

我現在面臨的問題是:

欲產生一些代碼,基於註釋的文件放置在兩個模塊 - A和B.問題來自注釋處理器的工作方式 - 只與源代碼文件* .java - 不是編譯的* .class。不幸的是,在編譯B期間,註釋處理器無法訪問A中的源文件...

唯一的問題是,我能夠考慮作爲一種解決方案,即使是一個醜陋的解決方案,將包含來自模塊A的註釋類的文件夾作爲模塊B的源設置。這樣,我可以在編譯期間讓模塊B訪問這些文件。

sourceSets { 
    main { 
     java { 
      srcDirs = ['src/main/java', '../module_A/src/main/java/path/to/annotated/classes/folder'] 
     } 
    } 
} 

這解決了問題 - 現在的註解處理器已經獲得來自兩個模塊的所有類中的註解,但是......

不幸的是,它引入了另一個問題......從模塊A的註解類,現在編譯兩次。它們包含在模塊A的JAR文件和模塊B的AAR文件中。

問題1:是否有另一種方式從B上運行的註釋處理器訪問模塊A的源文件? (從我能找到的答案是NO,但是檢查...)

問題2:如何從模塊B的AAR最終包中排除那些編譯的文件(重複的)?

問題3:也許......這是一個絕對錯誤的方法?有什麼建議麼?

提前致謝!

回答

1

Nop,你只用java.lang.model API就無法達到你想要的效果。至少不是沒有一些額外的技巧。

問題不在於二進制與源代碼。註解處理器可以使用Elements#getTypeElement到interospect編譯的類以及源定義的類:

Elements elementUtil = processingEnvironment.getElementUtils(); 
TypeElement integerClass = elementUtil.getTypeElement("java.lang.Integer"); 
TypeElement myClass = elementUtil.getTypeElement("currently.compiled.Class"); 

但你仍然需要對編譯類路徑類來觀察它,類必須在過程中被編譯成可見到getElementsAnnotatedWith

你可以通過使用像FastClasspathScanner這樣的工具來解決後面的限制:它將使用它自己的機制在編譯的字節碼中查找註釋,並從編譯過程中單獨報告給你。但是你不能解決類路徑問題:如果你在編譯類路徑中沒有某種依賴性,它就不能被處理。所以你編譯模塊在一起 - 要麼合併成一個(如你所做的),要麼通過聲明一個依賴另一個。在以後的情況下,您可能無法使用getElementsAnnotatedWith,但getTypeElement和FastClasspathScanner可以使用。

+0

感謝您的回答,但我有點困惑:在當前狀態模塊B取決於A. – ivtoto

+0

感謝您的回答,但我有點困惑:在當前狀態**模塊B已經取決於A **。因此,它應該可以訪問A中的編譯類,因爲它被定義爲編譯依賴項:'dependencies {compile project(':A')}'。而且,可能會更具體些,關於你提到的'getTypeElement' – ivtoto

+0

@ivtoto我的回答已經鏈接到'Elements#getTypeElement'的文檔。我還添加了一個使用它的例子。文檔中是否有某些內容,對您而言還不清楚?也許,你應該做一些研究,並可能提出一個額外的問題。 – user1643723