在更新到Android Studio 3.0并创建一个新项目后,我注意到在构建中。gradle有一种新方法来添加新的依赖项,而不是compile,而是implementation,而不是testCompile,而是testimplemimplementation。
例子:
implementation 'com.android.support:appcompat-v7:25.0.0'
testImplementation 'junit:junit:4.12'
而不是
compile 'com.android.support:appcompat-v7:25.0.0'
testCompile 'junit:junit:4.12'
它们之间的区别是什么,我应该用什么?
implementation: mostly we use implementation configuration. It hides the internal dependency of the module to its consumer to avoid accidental use of any transitive dependency, hence faster compilation and less recompilation.
api: must be used very carefully, since it leaks the to consumer’s compile classpath, hence misusing of api could lead to dependency pollution.
compileOnly: when we don’t need any dependency at runtime, since compileOnly dependency won’t become the part of the final build. we will get a smaller build size.
runtimeOnly: when we want to change or swap the behaviour of the library at runtime (in final build).
我已经创建了一个深入了解每个工作示例的帖子:源代码
https://medium.com/@gauraw.negi/how-gradle-dependency-configurations-work-underhood-e934906752e5
博士tl;
只是替换:
使用实现(如果你不需要传递性)或API(如果你需要传递性)编译
使用testimplemimplementation进行testCompile
使用debugImplementation进行debugCompile
androidTestCompile与androidTestImplementation
compileOnly仍然有效。它是在3.0中添加的,用于替换提供的和不编译的。(当Gradle没有为该用例提供配置名称时,就引入了该用例,并以Maven提供的作用域命名。)
这是谷歌在IO17大会上宣布的Android Gradle插件3.0的突破性变化之一。
compile配置现在已弃用,应该由实现或api取代
来自Gradle文档:
dependencies {
api("commons-httpclient:commons-httpclient:3.1")
implementation("org.apache.commons:commons-lang3:3.5")
}
Dependencies appearing in the api configurations will be
transitively exposed to consumers of the library, and as such will
appear on the compile classpath of consumers.
Dependencies found in the implementation configuration will, on the
other hand, not be exposed to consumers, and therefore not leak into
the consumers' compile classpath. This comes with several benefits:
dependencies do not leak into the compile classpath of consumers anymore, so you will never accidentally depend on a transitive
dependency
faster compilation thanks to reduced classpath size
less recompilations when implementation dependencies change: consumers would not need to be recompiled
cleaner publishing: when used in conjunction with the new maven-publish plugin, Java libraries produce POM files that
distinguish exactly between what is required to compile against the
library and what is required to use the library at runtime (in other
words, don't mix what is needed to compile the library itself and what
is needed to compile against the library).
The compile configuration still exists, but should not be used as it will not offer the guarantees that the api and implementation configurations provide.
注意:如果你只在你的app模块中使用一个库——通常情况下——你不会注意到任何区别。
只有当您有一个相互依赖的模块的复杂项目,或者您正在创建一个库时,您才会看到区别。
在继续之前先做一些笔记;compile已弃用,并且文档声明您应该使用implementation,因为compile将在Gradle 7.0版本中被删除。
如果你使用——warning-mode运行Gradle构建,你会看到以下消息:
对于依赖项声明,compile配置已弃用。这将失败,并在Gradle 7.0中出现错误。请改用实现配置。
只要看看帮助页上的图片,就很有意义了。
你有蓝色框compileClasspath和runtimeClassPath。
当运行gradle build时,compileClasspath是成功构建所必需的。编译时将出现在类路径上的库将是在gradle构建中使用compileOnly或implementation配置的所有库。
然后我们有runtimeClasspath,这些都是使用实现或runtimeOnly添加的包。所有这些库都将添加到您部署到服务器上的最终构建文件中。
如图所示,如果您希望一个库既用于编译,又希望将它添加到构建文件中,那么应该使用实现。
runtimeOnly的示例可以是数据库驱动程序。
compileOnly的一个例子可以是servlet-api。
实现的一个例子是spring-core。