什么';Gradle中实现和编译的区别是什么?
在升级到Android Studio 3.0并创建了一个新项目后,我注意到在什么';Gradle中实现和编译的区别是什么?,gradle,build.gradle,dependency-management,gradle-plugin,transitive-dependency,Gradle,Build.gradle,Dependency Management,Gradle Plugin,Transitive Dependency,在升级到Android Studio 3.0并创建了一个新项目后,我注意到在build.gradle中有一种新的方法来添加新的依赖项,而不是compile有实现,而不是testCompile有测试实现 例如: implementation 'com.android.support:appcompat-v7:25.0.0' testImplementation 'junit:junit:4.12' 而不是 compile 'com.android.support:appcompat-v7:
build.gradle
中有一种新的方法来添加新的依赖项,而不是compile
有实现
,而不是testCompile
有测试实现
例如:
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'
它们之间有什么区别?我应该使用什么?tl;dr
只需替换:
使用
实现编译
(如果不需要传递性)或
(如果需要传递性)api
withtestCompile
testImplementation
withdebugCompile
debugImplementation
withandroidTestCompile
androidTestImplementation
仍然有效。它是在3.0中添加的,用于替换提供的而不是编译。(compileOnly
在Gradle没有该用例的配置名称时引入,并以Maven提供的范围命名。)provided
compile
配置是并且应该被implementation
或api
从:
api
配置中出现的依赖项将被删除
过渡地向图书馆的消费者公开,因此
出现在使用者的编译类路径上
在实现
配置中找到的依赖项将在
另一方面,不会接触到消费者,因此不会泄漏到产品中
使用者的编译类路径。这有几个好处:
- 依赖项不再泄漏到使用者的编译类路径中,因此您永远不会意外地依赖于传递类 依赖性
- 由于减小了类路径大小,编译速度更快
- 实现依赖项更改时减少重新编译:消费者不需要重新编译
- cleaner publishing:当与新的maven publish插件结合使用时,Java库生成POM文件 准确区分根据 库以及在运行时使用库所需的内容(在其他情况下) 换句话说,不要混淆编译库本身所需的内容和 需要根据库进行编译)
api
和实现
配置提供的保证。
注意:如果您只在应用程序模块中使用库(常见情况),您不会注意到任何差异。
只有当您有一个模块相互依赖的复杂项目,或者您正在创建一个库时,您才会看到差异。
Compile
配置已被弃用,应被实现
或api
取代
您可以在以下位置阅读文档:
简短的部分是-
标准Java插件和Java
库插件是后者引入了API的概念
接触消费者。库是一个Java组件,用于
被其他组件消耗。这是一个非常常见的用例
多项目构建,但也要在有外部
依赖关系
该插件公开了两种可用于声明的配置
依赖项:api和实现。api配置应该是
用于声明库API导出的依赖项,
然而,应该使用实现配置来声明
组件内部的依赖项
有关更多说明,请参阅此图。
简要解决方案: 更好的方法是将所有
编译
依赖项替换为实现
依赖项。只有在泄露模块接口的地方,才应该使用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 plugin 3.0之前:我们遇到了一个大问题,就是代码更改导致所有模块重新编译。根本原因是Gradle不知道是否通过另一个模块泄漏模块接口 安卓Gradle插件3.0之后:最新的安卓Gradle插件现在要求您明确定义是否泄漏模块接口。基于此,它可以在应该重新编译的内容上做出正确的选择 因此,
compile
依赖项已被弃用,并被两个新依赖项取代:
:您通过自己的接口泄漏此模块的接口,这与旧的api
依赖项完全相同compile
:您只在内部使用此模块,不会通过接口泄漏实现
由blog提供此答案将展示项目上
实现
、api
和编译
之间的区别
假设我有一个包含三个Gradle模块的项目:
- 应用程序(安卓应用程序)
- myandroidlibrary(Android库)
- myjavalibrary(一个Java库)
app
将myandroidlibrary
作为依赖项myandroidlibrary
将myjavalibrary
作为依赖项
myjavalibrary
有一个MySecret
类
public class MySecret {
public static String getSecret() {
return "Money";
}
}
myandroidlibrary
具有MyAndroidComponent
类,该类操作MySecret中的值
public class MySecret {
public static String getSecret() {
return "Money";
}
}
public class MyAndroidComponent {
private static String component = MySecret.getSecret();
public static String getComponent() {
return "My component: " + component;
}
}
TextView tvHelloWorld = findViewById(R.id.tv_hello_world);
tvHelloWorld.setText(MyAndroidComponent.getComponent());
dependencies {
implementation project(':myandroidlibrary')
}
dependencies {
// Option #1
implementation project(':myjavalibrary')
// Option #2
compile project(':myjavalibrary')
// Option #3
api project(':myjavalibrary')
}
TextView textView = findViewById(R.id.text_view);
textView.setText(MyAndroidComponent.getComponent());
// You can access MySecret
textView.setText(MySecret.getSecret());
TextView textView = findViewById(R.id.text_view);
textView.setText(MyAndroidComponent.getComponent());
// You can NOT access MySecret
textView.setText(MySecret.getSecret()); // Won't even compile
+--------------------+----------------------+-------------+--------------+-----------------------------------------+
| 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. |
+--------------------+----------------------+-------------+--------------+-----------------------------------------+