Gradle —— implementation, api 这些
在声明第三方依赖时,我们需要告诉 Gradle 在什么地方去获取这些依赖,即配置 Gradle 的 Repository。
repositories {
mavenCentral()
}
Configuration 概念
Gradle 将对依赖进行分组,比如编译 Java 代码时使用一组,运行 Java 代码时有使用另一组依赖。每一组依赖我们称为一个 Configuration,在声明依赖时,实际上是在设置不同的 Configuration。定义一个 Configuration:
configurations {
myDependency
}
通过以上方法,我们定义了一个名为 myDependency
的 Configuration,但是我们还未向其中加入具体的依赖项(也就是这个 Configuration 中的具体元素)。我们可以通过 dependencies()
方法向 myDependency
中加入实际的依赖项:
dependencies {
myDependency 'org.apache.commons:commons-lang3:3.0'
}
之后如果有 Task 需要使用 Apache Commons,比如需要将其加入到 classpath 中,我们可以通过以下方式进行获取:
task showMyDependency {
doLast {
println configurations.myDependency.asPath
}
}
执行 showMyDependency
显示如下:
Task :showMyDependency
/Users/joe.yang/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.0/8873bd0bb5cb9ee37f1b04578eb7e26fcdd44cb0/commons-lang3-3.0.jar
通过自定义 Configuration,Plugin 可以管理 Configuration 中依赖项的作用域。比如 JavaPlugin 就自定义了两个 Configuration:implementation
和 testRuntime
,它们分别是一个用于编译代码,一个用于运行测试代码。
Configuration 的继承
比如你想写一个用于冒烟测试的依赖集合,每一个测试用例都需要访问网络,而 Plugin 中自带的测试集合 testImplementation
已经有 junit
了,那么就只需要再自定义一个继承自 testImplementation
的 Configuration,并向这个 Configuration 中加上网络依赖就可以了。
configurations {
smokeTest.extendsFrom testImplementation
}
dependencies {
testImplementation 'junit:junit:4.12'
smokeTest 'org.apache.httpcomponents:httpclient:4.5.5'
}
文件依赖
我们所需依赖的三方库并不总是在远程 Maven 仓库上,而是通过本地的 .jar 或 .aar 文件的形式存在的。文件依赖的写法可以参考 Android Studio 中自动生成的 build.gradle
脚本来看:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
文件依赖是不受 Gradle 的版本冲突解决方案约束的。因此使用文件依赖时,就只能通过将版本号写到文件名里来人工管理了。
Android 中的 implementation
和 api
Android 中最常用的就是 implementation
和 api
,推荐使用 implementation
。
implementation
具有阻断性,而 api
具有穿透性,这两个结合使用时是否就产生了矛盾?比如 module child api
依赖了 org.apache.httpcomponents:httpclient:4.5.5
,module parent implementation
依赖了 module child,那么 parent 其实在非运行阶段使用不了 httpclient
的任何功能。parent 通过 implementation
实现了编译隔离。