我啥时候需要在 Gradle 依赖项中使用 Kapt?
Posted
技术标签:
【中文标题】我啥时候需要在 Gradle 依赖项中使用 Kapt?【英文标题】:When do I need to use Kapt in Gradle dependencies?我什么时候需要在 Gradle 依赖项中使用 Kapt? 【发布时间】:2019-11-03 14:46:44 【问题描述】:我一直在 Gradle 中安装依赖项,但我不明白为什么有时我需要将 kapt 用于生命周期和房间数据库等库以使用 @Something
注释。但是在Retrofit2和Gson等一些库中,我不需要使用kapt,我可以使用@SerializedName
等注解?
【问题讨论】:
【参考方案1】:注解(例如@Something
)基本上是代码的标签。您标记代码的一部分,以便一些其他代码可以找到这些标记。
这个“其他代码”通常是一个注解处理器。它找到注释并使用标记有这些注释的代码执行某些操作。例如。它可以生成新代码(如 Dagger、Butterknife 等)。
取决于您在项目中引入依赖项的方式,(取决于您使用的keyword
- implementation
、api
、compileOnly
、runtimeOnly
、annotationProcessor
、kapt
等。 ),您的项目将使用不同的依赖项。
如果您使用annotationProcessor
,您的依赖项将不会打包在您的应用程序中,但会在您的应用程序编译期间使用。
您不想在您的应用中打包编译器(处理@AnAnnotation
的代码),因为它只是用于正确准备您的应用的代码(并且从未在运行时的应用中使用)。
这样想:
如果您要上火车,并且需要打印火车票,您不想在火车上随身携带打印机。打印机打印完票后,你拿着票上火车。打印机已经完成了它的工作。你可以离开它。
如果您使用@AnAnnotation
标记某些代码,您只希望处理该注释的库完成其工作并消失。因此特殊类型的依赖 - annotationProcessor
.
现在关于kapt
。这很简单。如果您想在带有 Kotlin 代码的项目中使用注释处理器,只需使用 kapt
而不是 annotationProcessor
。可以把它想象成 annotationProcessor
并支持 Kotlin。
一些库以不同的方式使用@Annotations
。它们不会导致在编译时生成任何代码,但它们在运行时使用注释。
那些通常是基于反射的库,可在运行时“查看”代码。就像 Retrofit 在您的应用程序执行时查看您的 interface
一样。
这就是为什么您通常在您的应用程序中包含一个带有@Annotations
的库,并且这些注释被打包在您的 apk 中以进行运行时操作。
总结:
annotationProcessor
和 kapt
关键字用于帮助您指定在项目中将如何使用依赖项。
如果您想引入一个使用注释并生成一些代码的库,请使用kapt
,不要用已经完成工作且永远不会再次使用的代码“膨胀”您的 apk。
【讨论】:
@WayFaiGodfreyCheng 如果对您有帮助,请随时接受答案【参考方案2】:通常,库通过以下两种方式之一与注解进行交互:
使用反射。库代码可以在运行时查询注释以执行某些逻辑。这些库通常会打包为单个工件,不需要使用kapt
或annotationProcessor
。示例:Retrofit,它使用反射访问注释并且不包含注释处理器。
使用注释处理器。注释处理器是编译器插件,在主要编译步骤之前被调用,可以访问注释及其周围的代码,并根据此输入执行任务。注释处理器通常包含在单独的工件中,因为它们包含运行时不需要的代码,因此不应将其打包到您的 APK 中。示例:Butterknife,它在编译期间处理注释,并带有一个单独的 butterknife-compiler
模块,其中包含注释处理器。您应该使用butterknife-compiler
作为kapt
或annotationProcessor
依赖项,而不是implementation
、api
或compile
,因为在运行时不需要注释处理器。
要回答您的问题,没有通用方法可以知道依赖注释的库是否带有注释处理器。您应该查看特定库的文档并按照安装说明进行操作。
【讨论】:
以上是关于我啥时候需要在 Gradle 依赖项中使用 Kapt?的主要内容,如果未能解决你的问题,请参考以下文章
Android apk - 如何使用 gradle 从 3rd 方依赖项中排除 .so 文件
在 gradle 传递依赖项中检测 Apache Log4j 漏洞的存在
Android Studio - Gradle 实现 (...) exclude ... 不起作用(无法从依赖项中排除组)