mal*_*din 11 java android annotation-processing dagger-2 annotation-processor
我编写了一个简单的 Annotation Processor(只是为了好玩),它将生成一些我在之前的项目中编写的样板代码。它实际上通过收集 Activity 类的注释来生成如下模块
@Module
abstract class ActivityInjectorModule {
@ContributesAndroidInjector
abstract fun providesMain2Activity(): Main2Activity
@ContributesAndroidInjector
abstract fun providesMainActivity(): MainActivity
}
Run Code Online (Sandbox Code Playgroud)
但是,当我使用 dagger 运行它时,dagger 似乎无法找到我的 annotation processor 生成的类。虽然生成了类并存在于生成的目录中,但我可以在我的源代码中使用它,但是在编译时,dagger 会产生以下异常。有什么专家建议吗?
error: cannot find symbol
@dagger.Component(modules = {dagger.android.AndroidInjectionModule.class, com.mallaudin.daggietest.di.AppModule.class, ActivityInjectorModule.class})
^
symbol: class ActivityInjectorModule
Run Code Online (Sandbox Code Playgroud)
这是主要的应用程序组件。
@Singleton
@Component(
modules = [
AndroidInjectionModule::class,
AppModule::class,
ActivityInjectorModule::class
]
)
interface AppComponent : AndroidInjector<App> {
@Component.Builder
interface Builder {
fun addContext(@BindsInstance ctx: Context): Builder
fun build(): AppComponent
}
}
Run Code Online (Sandbox Code Playgroud)
ActivityInjectorModule类由注解处理器生成,存在于生成目录中。
应用类
class App : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.builder().addContext(this).build()
}
}
Run Code Online (Sandbox Code Playgroud)
一切正常,如果我自己创建生成的类。不知何故,在编译时,我的注释处理器生成时,dagger 无法找到该类。
在 Yuriy Kulikov 回答之后,
您可以看到生成的文件在同一个包中,但也使用完全限定名称引用。仍然匕首报告错误。
如果有人想进行实验,这里是github 存储库的链接
ese*_*sov 10
解决方案:
Kapt 不支持多轮。解释:
Javac注释处理器使用轮次而不是定义处理器顺序。所以通常简化的算法是这样的:
true,表明这是最后一轮。现在有点关于kapt. Kapt 使用 javac来运行注解处理器。为了使它成为可能,它首先运行 kotlin 编译器来生成 java 存根文件并javac在它们上运行。目前kapt 不支持多轮,这意味着它不会为 kotlin 类生成 Java 存根,由注释处理器生成。
注意:javac仍然使用多轮,只是无法获取生成的 kotlin 源。
那么,回到你的问题。一种可能的选择是将您生成的类移动到一个单独的模块中,就像这里描述的那样。
但是最简单的选择是直接生成java代码,你生成的java类会被javac自动拾取,启动第二轮注解处理,dagger会处理它们。
还有一些注意事项:
RoundEnvironment.processingOver() == true,它不会触发另一轮。在您看到注释的同一轮中生成它。新答案 我不知何故错过了你正在使用 kapt。如果你将其添加到你的 build.gradle 中,即使没有完整的限定名称(这很了不起),Kapt 也可以处理你的类:
kapt {
arguments {
arg("argumentIncremental", 'true')
}
correctErrorTypes = true
}
Run Code Online (Sandbox Code Playgroud)
有关此的更多信息: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})
Run Code Online (Sandbox Code Playgroud)
或者将这两个文件放在同一个包中。
长答案:Dagger 是一个注释处理器,它在编译代码之前运行,并且(可能)在其他注释处理器运行之前运行。处理器运行的顺序未定义。
Dagger 注释处理器将处理用 @dagger.Component 注释的 TypeElement,并尝试查找包括“ActivityInjectorModule.class”在内的所有模块。问题是,ActivityInjectorModule 可能尚未生成。因此“ActivityInjectorModule”此时不会有包。Dagger 将假定 ActivityInjectorModule 与 Component 类位于同一包中,并且不会添加导入。通常的解决方法是使用生成的类的完全限定名称(如果其他注释处理器使用它们)。有时将注释处理移至差异 gradle 模块是有意义的,但我不认为这就是您想要的。
| 归档时间: |
|
| 查看次数: |
2321 次 |
| 最近记录: |