Gradle 中的依赖关系 - chuwuwang/ReadingNote GitHub Wiki
implementation和api
implementation和api是取代之前的compile的,其中api和compile是一样的效果,implementation有所不同,通过implementation依赖的库只能自己库本身访问。
compileOnly
compileOnly和provided效果是一样的,只在编译的时候有效,不参与打包。
runtimeOnly
runtimeOnly和apk效果一样,只在打包的时候有效,不参与编译。
testImplementation
testImplementation和testCompile效果一样,在单元测试和打包测试apk的时候有效。
debugImplementation
debugImplementation和debugCompile效果相同,在debug模式下有效。
releaseImplementation
releaseImplementation和releaseCompile效果相同,只在release模式和打包release包情况下有效。
如何排除依赖
dependencies中排除(细粒度)
compile('com.taobao.android:accs-huawei:1.1.2@aar') {
transitive = true
exclude group: 'com.taobao.android', module: 'accs_sdk_taobao'
}
全局配置排除
configurations {
compile.exclude module: 'cglib'
// 全局排除原有的tnet jar包与so包分离的配置,统一使用aar包中的内容
all*.exclude group: 'com.taobao.android', module: 'tnet-jni'
all*.exclude group: 'com.taobao.android', module: 'tnet-so'
}
禁用依赖传递
compile('com.zhyea:ar4j:1.0') {
transitive = false
}
configurations.all {
transitive = false
}
举个例子: 假设 A 依赖 B,B 依赖 C。
-
如果 B 对 C 使用 implementation 依赖,则 A 无法调用 C 的代码。
-
如果 B 对 C 使用 api 依赖,则 A 可以调用 C 的代码。
-
如果 B 对 C 使用 compileOnly 依赖,则 A 无法调用 C 的代码,且 C 的代码不会被打包到 APK 中。
-
如果 B 对 C 使用 runtimeOnly 依赖,则 A、B 无法调用 C 的代码,但 C 的代码会被打包到 APK 中。
实际上每一个组件都有自己的 compileClasspath 和 runtimeClasspath。当一个组件参与编译时,Gradle 就会将其放在 compileClasspath 中。当一个组件参与打包时,Gradle 就会将其放在 runtimeClasspath 中。
不同的依赖配置项,其实就是将声明的依赖放入不同组件的不同的 classpath 中,回到上面的例子。对于 implementation ,其实就是将 C 放入 B 的 compileClasspath 和 runtimeClasspath,放入 A 的 runtimeClasspath 中,从而实现 A 如果调用 C 的代码,在 A 的编译阶段 javac 报错,但最终 C 会被打包到 APK 包中。对于 api、compileOnly、runtimeOnly 原理相同。