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 原理相同。


https://juejin.im/post/6844903741297016840

https://blog.csdn.net/wangli0829/article/details/81366095