在更新到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'

它们之间的区别是什么,我应该用什么?


当前回答

门外汉术语的简单区别是:

如果你正在处理一个接口或模块,它通过公开所声明的依赖关系的成员来为其他模块提供支持,你应该使用'api'。 如果你正在创建一个应用程序或模块,要在内部实现或使用声明的依赖项,请使用'implementation'。 'compile'与'api'工作方式相同,但是,如果你只是实现或使用任何库,'implementation'将更好地工作并节省资源。

阅读@aldok的回答以获得一个全面的示例。

其他回答

简单的解决方案:

更好的方法是用实现依赖替换所有编译依赖。只有在泄露模块接口时,才应该使用api。这应该会减少大量的重新编译。

 dependencies {
         implementation fileTree(dir: 'libs', include: ['*.jar'])
 
         implementation 'com.android.support:appcompat-v7:25.4.0'
         implementation 'com.android.support.constraint:constraint-layout:1.0.2'
         // …
 
         testImplementation 'junit:junit:4.12'
         androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
             exclude group: 'com.android.support', module: 'support-annotations'
         })
 }

解释:

在Android Gradle插件3.0之前:我们遇到了一个大问题,即一个代码更改导致所有模块被重新编译。造成这种情况的根本原因是Gradle不知道你是否通过另一个模块泄露了一个模块的接口。

在Android Gradle插件3.0之后:最新的Android Gradle插件现在要求你显式定义是否泄露了模块的接口。在此基础上,它可以对应该重新编译的内容做出正确的选择。

因此,compile依赖项已被弃用,并被两个新的依赖项所取代:

Api:你通过你自己的接口泄露了这个模块的接口,这意味着和旧的编译依赖完全一样 实现:你只在内部使用这个模块,不会通过你的接口泄露它

所以现在你可以显式地告诉Gradle重新编译一个模块,如果使用的模块的接口改变与否。

由Jeroen Mols博客提供

编译配置已弃用,应由实现或api取代。

你可以在API和实现分离部分阅读文档。

简短的部分是

The key difference between the standard Java plugin and the Java Library plugin is that the latter introduces the concept of an API exposed to consumers. A library is a Java component meant to be consumed by other components. It's a very common use case in multi-project builds, but also as soon as you have external dependencies. The plugin exposes two configurations that can be used to declare dependencies: api and implementation. The api configuration should be used to declare dependencies which are exported by the library API, whereas the implementation configuration should be used to declare dependencies which are internal to the component.

进一步的解释请参考这张图片。

其他答案解释了这种差异。

只要确保对于Kotlin DSL (build.gradle.kts),函数应该有圆括号,它们的字符串参数应该用双引号括起来,而不是单引号:

Groovy (build.gradle) 实现“com.android.support: appcompat-v7:25.0.0” testImplementation“junit: junit: 4.12” 芬兰湾的科特林(build.gradle.kts) 实现(“com.android.support: appcompat-v7:25.0.0”) testImplementation(“junit: junit: 4.12”)

在继续之前先做一些笔记;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。

+--------------------+----------------------+-------------+--------------+-----------------------------------------+
| Name               | Role                 | Consumable? | Resolveable? | Description                             |
+--------------------+----------------------+-------------+--------------+-----------------------------------------+
| api                | Declaring            |      no     |      no      | This is where you should declare        |
|                    | API                  |             |              | dependencies which are transitively     |
|                    | dependencies         |             |              | exported to consumers, for compile.     |
+--------------------+----------------------+-------------+--------------+-----------------------------------------+
| implementation     | Declaring            |      no     |      no      | This is where you should                |
|                    | implementation       |             |              | declare dependencies which are          |
|                    | dependencies         |             |              | purely internal and not                 |
|                    |                      |             |              | meant to be exposed to consumers.       |
+--------------------+----------------------+-------------+--------------+-----------------------------------------+
| compileOnly        | Declaring compile    |     yes     |      yes     | This is where you should                |
|                    | only                 |             |              | declare dependencies                    |
|                    | dependencies         |             |              | which are only required                 |
|                    |                      |             |              | at compile time, but should             |
|                    |                      |             |              | not leak into the runtime.              |
|                    |                      |             |              | This typically includes dependencies    |
|                    |                      |             |              | which are shaded when found at runtime. |
+--------------------+----------------------+-------------+--------------+-----------------------------------------+
| runtimeOnly        | Declaring            |      no     |      no      | This is where you should                |
|                    | runtime              |             |              | declare dependencies which              |
|                    | dependencies         |             |              | are only required at runtime,           |
|                    |                      |             |              | and not at compile time.                |
+--------------------+----------------------+-------------+--------------+-----------------------------------------+
| testImplementation | Test dependencies    |      no     |      no      | This is where you                       |
|                    |                      |             |              | should declare dependencies             |
|                    |                      |             |              | which are used to compile tests.        |
+--------------------+----------------------+-------------+--------------+-----------------------------------------+
| testCompileOnly    | Declaring test       |     yes     |      yes     | This is where you should                |
|                    | compile only         |             |              | declare dependencies                    |
|                    | dependencies         |             |              | which are only required                 |
|                    |                      |             |              | at test compile time,                   |
|                    |                      |             |              | but should not leak into the runtime.   |
|                    |                      |             |              | This typically includes dependencies    |
|                    |                      |             |              | which are shaded when found at runtime. |
+--------------------+----------------------+-------------+--------------+-----------------------------------------+
| testRuntimeOnly    | Declaring test       |      no     |      no      | This is where you should                |
|                    | runtime dependencies |             |              | declare dependencies which              |
|                    |                      |             |              | are only required at test               |
|                    |                      |             |              | runtime, and not at test compile time.  |
+--------------------+----------------------+-------------+--------------+-----------------------------------------+