一、概念
项目自动化构建管理,可以使用 Groovy DSL 语言(文件后缀xxx.gradle)或 Kotlin DSL 语言(文件后缀 xxx.gradle.kts)编写。
二、全局设置 settings.gradle
是整个 Gradle 项目构建的入口点,这里配置的都是全局的。构件时会生成一个 Settings 对象,这些简短的 DSL 语法底层都是在该对象上进行调用的。
| Settings对象常用属性及方法 | 说明 |
| buildCache | 缓存配置。 |
| plugins | 声明使用到的插件(全局)。 |
| rootDir | 根目录。 |
| rootProject | 根项目(该工程)。 |
| settings | 返回构建时通过该文件实例化出的 Settings 对象。 |
| include() | 将子模块添加到构建列表中(传入名称)。 |
| includeBuild() | 将其它 Gradle 工程添加到构建列表中(传入路径)。 |
2.1 配置插件和依赖的仓库地址
内置的仓库能函数直接调用,自定义的要用 maven() 来指定地址。
// 插件管理
pluginManagement {
// 仓库列表
repositories {
// 指定地址
// 阿里云镜像仓库加速访问
maven("https://maven.aliyun.com/repository/gradle-plugin")
maven("https://maven.aliyun.com/repository/public")
maven("https://maven.aliyun.com/repository/central")
maven("https://maven.aliyun.com/repository/apache-snapshots")
maven("https://maven.aliyun.com/repository/google")
// Google插件仓库
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
// Maven中心仓库
mavenCentral()
// Gradle插件仓库
gradlePluginPortal()
}
}
// 依赖解析管理(更推荐在 build.gradle 文件中配置)
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven("https://maven.aliyun.com/repository/gradle-plugin")
maven("https://maven.aliyun.com/repository/public")
maven("https://maven.aliyun.com/repository/central")
maven("https://maven.aliyun.com/repository/apache-snapshots")
maven("https://maven.aliyun.com/repository/google")
google()
mavenCentral()
}
}
2.2 配置插件
Gradle 插件可以帮助我们在构建过程中实现各种各样的高级功能,用于扩展任务(tasks)或构建逻辑。
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
2.3 添加子模块
让子模块参与到构建中。构件时会先读取 Settings.gradle,根据声明再去读取子模块中的 build.gradle 文件)。
// rootProject 代表工程,name 属性是其名称
rootProject.name = "Demo"
// 添加子模块,没有子模块可以不写
include("base")
三、模块配置 build.gradle
针对构建进行配置。对于 Settings.gradle 中声明的子模块,Gradle 都会为其生成一个 Project 对象,这些简短的 DSL 语法底层都是在该对象上进行调用的。
| Project对象常用属性及方法 | 说明 |
| name | 模块名称。 |
| path | 模块路径。 |
| description | 模块描述。 |
| dependencies | 配置模块的依赖列表。 |
| repositories | 配置模块的依赖仓库。 |
| layout | 通过此对象访问模块的关键位置。 |
| group | 模块的组。 |
| version | 模块的版本。 |
3.1 配置插件
// 指定项目需要使用到的插件
plugins {
id("org.jetbrains.kotlin.jvk") version "1.9.0" // 普通方式
alias(libs.plugins.android.application) apply false // toml方式
}
3.2 配置依赖
普通方法仅用于当前模块,带有 api 版本的方法可向上传递(引入这个模块的上层模块不用重复添加依赖项)。
| DependencyHandlerScope的方法 | 说明 |
|
implementation api | 添加依赖。 |
| compileOnly | 仅在编译时可用,不会包含在最终构建结果中(编译完不会一起打包)。 |
| runtimeOnly | 仅在运行时使用,不用于编译。如 MySQL 驱动不需要在项目编程时使用,但在程序运行时需要用到。 |
|
testImplementation testApi | 测试时需要的依赖。 |
|
androidTestImplementation androidTestApi | Android测试时需要的依赖。 |
|
debugImplementation debugApi | debug时需要的依赖。 |
| kapt | 用于添加 Kotlin 注解处理器依赖项 |
| annotationProcessor | 用于添加 Java 朱家琪依赖项。 |
3.2.1 添加
dependencies {
// 引入仓库中的依赖
implementation("io.coil-kt.coil3:coil-compose:3.5.0") // 普通方式
implementation(libs.compose.material3) // 通过 toml 的方式
// 导入本地jar包(存放在根目录的lib里)
// 需要一个包一个包写
implementation(
files(
"lib/spring-context-6.1.3.jar",
"lib/spring-core-6.1.3.jar"
)
)
// 直接给目录
implementation(fileTree("lib"))
}
3.2.2 排除、强制(解决冲突)
一个依赖里会有前置依赖(该依赖还依赖别的),有时会有冲突,可以排除该依赖中的前置依赖。
implementation("org.springframework:string-context:6.1.3") {
exclude("org.springframework") // 排除整个组
exclude("org.springframework:spring-aop") // 排除具体某一个某块
}
spring-context 中包含了 spring-aop,当添加了 context 6.1.3 又添加了 aop 6.1.1 会优先使用更新的 aop 6.1.3。 此时可以通过排除不用最新的,也可以添加感叹号强制使用旧的。
// 两种方式二选一
implementation("org.springframework:string-context:6.1.3") {
exclude("org.springframework:spring-aop") // 不用新的
}
implementation("org.springframework:string-aop:6.1.1!!") // 双感叹号强制使用
四、自定义任务 Task
Gradle 的工作由一个或多个任务(Task)来定义,任务代表构建执行的独立工作单元,比如编译一些类、创建 jar 包、生成 JavaDoc 文档、将一些内容发布到代码仓库。这些任务由插件提供(最直观的感受就是那些用来配置的DSL语句,以及build后显示的各种Task信息),工程中引入插件后就可以执行对应的任务了。当然也可以在 build.gradle 中创建自定义任务。
4.1 创建任务
| register() | 懒加载,用到时才创建。 |
| create() | 普通创建。 |
IDE 代码左边可以点击箭头执行,也可以终端输入 ./gradle hello 执行。
// 第一个参数为任务名称,第二个参数 Lambda 为具体操作
tasks.register("hello") {
// 设置组(相同组名的任务会在IDE的Gradle面板里聚合显示)
group = ""
// 设置描述信息(终端输入 ./gradle tasks 会显示可用任务和描述)
description = ""
println("执行中")
// 插入到队列头部
doFirst {
println("任务开始")
}
// 插入到队列尾部
doLast {
println("任务结束")
}
}

4.2 默认任务
| defaultTasks() | 要传入已有任务名,终端输入 ./gradle 就会执行。 |
defaultTsks("hello") // 默认任务,传入已有任务名
4.3 前置任务
一个任务还可以依赖其它任务。
tasks.register("hello") {
// 执行自定义任务之前,需要先完成源代码编译
dependsOn(tasks.compileJava) // 也可以传任务名字符串
}
4.4 修改任务
| named() | 修改已有任务。 |
// 执行build前先执行我们的自定义任务
tasks.named("build") {
dependsOn("hello")
}
// 直接从tasks中获取build任务(仅限插件提供的任务)
tasks.build {
dependsOn("hello")
}
4.5 内置任务类型
上述提到的方法默认泛型都是<Task>类型,还可以指定为其它内置类型:Zip、Jar、Sign、Delete 等。
tasks.register<Copy>("hello") {
from("build/classes") // 复制的目录
into("test") // 目标位置
dependsOn("tasks.build") // 依赖一下前置任务
}
4.6 自定义任务类型
通过继承 DefaultTask 类来创建自定义任务类型,自定义的这个类必须可继承(要么open要么abstract)。
// 自定义
open class HelloTask : DefaultTask() {
private var name: String = ""
// 注解声明的函数才会在任务执行时被自动调用
@TaskAction
fun hello() { println("名字是:$name") }
// 也可以声明普通函数
fun setName(str: String) { name = str }
}
// 使用(运行会执行 HelloTask 中的 hello() 函数)
tasks.register<HelloTask>("hello") {
// 此时 this 就是 HelloTask 类型了
setName("张三") // 调用普通函数
}
五、生命周期钩子
可以在不同阶段执行自定义内容,如统计某一阶段或某个任务的耗时。
未特别说明的,在 settings.gradle 或 build.gradle 中都可以调用。
| 初始阶段 | gradle.settingsEvaluated() | 完成工程的配置阶段之后调用(只能定义在 setting.gradle 或 init.gradle 中)。 |
| gradle.projectsLoaded() | 所有模块加载之后调用(只能定义在 setting.gradle 或 init.gradle 中)。 | |
| 配置阶段 | gradle.beforeProject() | 每个模块完成配置之前调用(只能定义在 setting.gradle 或 init.gradle 中)。 |
| gradle.afterProject() | 每个模块配置完成之后调用。 | |
| gradle.projectsEvaluated() | 所有模块配置完成之后调用。 | |
| gradle.aftersEvaluated() | 整个配置阶段完成后调用。 | |
| gradle.taskGraph.whenReady() | 全部任务都已经构建完成时调用。 | |
| 执行阶段 | gradle.taskGraph.beforeTask() | 每个任务执行前调用。 |
| gradle.taskGraph.afterTask() | 每个任务执行后调用。 | |
| gradle.buildFinished() | 整个构建全部结束后调用 |
gradle.settingsEvaluated {
println("开始构建")
}
gradle.buildFinished {
println("结束构建")
}
统计每个任务的耗时:
var time = 0L
gradle.taskGraph.beforeTask {
time = System.currentTimeMillis()
}
gradle.taskGraph.afterTask {
val takeTime = System.currentTimeMillis - time
println("任务$name 耗时:$takeTime")
}
六、多模块
6.1 依赖其它模块
implemention(project(":module_base"))
6.2 统一配置
对多个模块进行统一配置,可以在根目录创建一个 build.gradle 来编写。
// 表示对所有子模块生效(用allprojects包括自己也生效)
subprojects {
// 定义插件,plugin()在这里不行了
apply(plugin = "java")
// 定义组
group = ""
// 定义版本
version = ""
// 定义仓库地址
repositories {
maven("https://maven.aliyun.com/repository/public")
}
}
6.3 依赖传递
A模块依赖B模块,可以调用B模块中的功能,C依赖A模块却不能调用B中的功能,就因为中间隔了一层。解决方法是将 implemention 改成 api ,参见上面 3.2。


96

被折叠的 条评论
为什么被折叠?



