3 回答

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超8個贊
解決方案:
生成java代碼。
Kapt
?不支持多輪。在盡可能早的一輪寫入生成的文件。
解釋:
Javac
注釋處理器使用回合而不是定義處理器順序。所以通常簡化的算法是這樣的:
收集所有 java 資源
運(yùn)行所有注釋處理器。任何注釋處理器都可以使用Filer生成新文件。
收集所有生成的文件,如果有,請?jiān)俅芜\(yùn)行步驟 2。
如果沒有生成文件,則再運(yùn)行一輪RoundEnvironment.processingOver()返回
true
,表示這是最后一輪。
這是對這個過程的一個很好的解釋
現(xiàn)在有點(diǎn)關(guān)于kapt
。Kapt
?使用 javac運(yùn)行注解處理器。為了使其成為可能,它首先運(yùn)行 kotlin compliler 以生成 java 存根文件并javac
在其上運(yùn)行。目前kapt
?不支持多輪,這意味著它不會為注釋處理器生成的 kotlin 類生成 java 存根。?注意:javac
仍然使用多輪,只是無法獲取生成的 kotlin 源代碼。
那么,回到你的問題。一種可能的選擇是將您生成的類移動到一個單獨(dú)的模塊中
但最簡單的選擇是直接生成 java 代碼,你生成的 java 類將被自動拾取javac
,啟動第二輪注釋處理,dagger 將在其中處理它們。
再補(bǔ)充幾點(diǎn):
不要在 時生成您的代碼
RoundEnvironment.processingOver() == true
,它不會觸發(fā)另一輪。在您看到注釋的同一輪中生成它。要使生成的代碼對注釋處理器可見,請使用Filer編寫它。

TA貢獻(xiàn)1906條經(jīng)驗(yàn) 獲得超3個贊
新答案 我以某種方式錯過了您正在使用 kapt。Kapt 可以處理你的類,即使沒有完整的限定名(這很了不起),如果你將它添加到你的 build.gradle 中:
kapt {
arguments {
arg("argumentIncremental", 'true')
}
correctErrorTypes = true
}
有關(guān)此的更多信息: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 是一個注釋處理器,它在您的代碼編譯之前運(yùn)行,并且(可能)在您的其他注釋處理器運(yùn)行之前運(yùn)行。處理器運(yùn)行的順序未定義。
Dagger 注釋處理器將處理用 @dagger.Component 注釋的 TypeElement,它會嘗試找到所有模塊,包括“ActivityInjectorModule.class”。問題是,ActivityInjectorModule 可能還沒有生成。因此“ActivityInjectorModule”此時不會有包。Dagger 將假定 ActivityInjectorModule 與 Component 類位于同一個包中,并且不會添加導(dǎo)入。通常的解決方法是為生成的類使用完全限定名稱,如果它們被其他注釋處理器使用的話。有時將注釋處理移動到不同的 gradle 模塊是有意義的,但我不認(rèn)為這是你想要的。

TA貢獻(xiàn)1788條經(jīng)驗(yàn) 獲得超4個贊
可能有更優(yōu)雅的方法來解決這個問題,但最簡單和最可靠的解決方案是執(zhí)行兩次傳遞 — 一次javac僅運(yùn)行注釋處理器,第二次執(zhí)行它通常執(zhí)行的所有操作。
該javac 文檔指定了兩個可以幫助您的選項(xiàng)。
-proc:{無,僅}
控制注釋處理和/或編譯是否完成。-proc:none 表示編譯在沒有注釋處理的情況下進(jìn)行。-proc:only表示只做注解處理,不做任何后續(xù)編譯。
-處理器類 1 [,類 2,類 3 ...]
要運(yùn)行的注釋處理器的名稱。這會繞過默認(rèn)的發(fā)現(xiàn)過程。
第一步(只運(yùn)行你自己的注解處理器)是
javac -proc:only -processor com.foo.bar.MyProcessor MyProject/src/*
第二遍(常規(guī)構(gòu)建)是
javac MyProject/src/*
如果您使用的是 Ant 或 Maven 之類的東西,您應(yīng)該能夠更新構(gòu)建指令,只需最少的工作量即可獲得兩次編譯器傳遞。
編輯:這是我對 Gradle 說明的嘗試
我沒有使用 Gradle 的經(jīng)驗(yàn),但看起來你需要做這樣的事情。
在您的 Gradle 構(gòu)建腳本中,您需要定義預(yù)處理任務(wù)并將對您的任務(wù)的依賴項(xiàng)添加到 javaCompile 任務(wù)。
javaCompile.dependsOn myAnnotationTask
task myAnnotationTask(type: JavaCompile) {
options.compilerArgs << '-proc:only' << '-processors com.foo.bar.MyAnnotationProcessor'
}
添加回答
舉報(bào)