1、Gradle入门:Gradle是什么、Gradle与Maven/Ant对比、Gradle Wrapper、Groovy vs Kotlin DSL、第一个Gradle脚本
说实话,我刚接触Android开发那会儿,对构建工具的理解就是「点一下运行按钮,App就出来了」。直到有一次,项目里需要接入十几个第三方SDK,还要区分不同渠道的包名和签名配置……嗯,那时候我才意识到,不懂Gradle,你连项目都跑不起来。
这一章,咱们就从头捋一捋Gradle到底是什么,它凭什么能成为Android开发的标配。
Gradle是什么?
Gradle是一个自动化构建工具。说白了,它帮你把源代码、资源文件、依赖库这些东西,按照你定好的规则,打包成APK或者AAB文件。
它跟传统的构建工具最大的区别在于两点:
- 基于Groovy或Kotlin的DSL——你写的构建脚本,本质上就是代码,可以做逻辑判断、循环、函数调用
- 增量构建——只编译修改过的部分,而不是每次都全量编译。我有个项目,第一次构建要5分钟,改一行代码再构建,只要20秒
Gradle的核心工作流程可以概括为三个阶段:
- 初始化阶段——解析settings.gradle,确定哪些模块参与构建
- 配置阶段——执行每个模块的build.gradle,生成Task依赖图
- 执行阶段——按依赖顺序执行Task
下面这张图帮你快速理解Gradle的整体架构:
Gradle vs Maven vs Ant
很多老项目还在用Maven或者Ant。我当年接手过一个用Ant构建的项目,那叫一个酸爽——依赖全靠手动下载,版本冲突全靠肉眼排查。后来迁移到Gradle,整个人都解脱了。
这三者的区别,我用一个表格给你说清楚:
| 对比维度 | Ant | Maven | Gradle |
|---|---|---|---|
| 构建脚本 | XML,冗长 | XML,约定大于配置 | Groovy/Kotlin DSL,简洁灵活 |
| 依赖管理 | 无,手动管理 | 内置,支持传递依赖 | 内置,支持动态版本、依赖锁定 |
| 性能 | 一般 | 较慢,全量构建 | 快,增量构建+构建缓存 |
| 扩展性 | 差,自定义逻辑困难 | 一般,插件开发复杂 | 强,自定义Task和插件简单 |
| Android支持 | 不原生支持 | 需额外配置 | 官方支持,Android插件 |
Gradle Wrapper
你有没有遇到过这种情况:从Git上拉下一个项目,一构建就报错,原因是本地Gradle版本跟项目要求的不一致?
Gradle Wrapper就是解决这个问题的。它把Gradle的版本信息固化在项目里,不管谁拉代码,用的都是同一个Gradle版本。
Wrapper的核心文件有这几个:
gradlew(Linux/Mac)和gradlew.bat(Windows)—— 启动脚本gradle/wrapper/gradle-wrapper.properties—— 版本配置gradle/wrapper/gradle-wrapper.jar—— 下载器
我个人习惯,所有项目都用Wrapper构建,而不是直接装全局Gradle。这样团队里每个人环境一致,省心。
生成Wrapper也很简单:
// 在项目根目录执行
gradle wrapper --gradle-version 8.4
执行完后,项目里就会出现上面说的那几个文件。以后别人拉代码,直接运行 ./gradlew build 就行,Wrapper会自动下载对应版本的Gradle。
gradle-wrapper.properties 里的 distributionUrl 改成国内镜像地址,下载速度能快10倍。我曾经在没网的环境下配过离线Wrapper,直接把Gradle zip包扔到 ~/.gradle/wrapper/dists/ 目录下就行。
Groovy vs Kotlin DSL
Gradle支持两种DSL:Groovy和Kotlin。早期版本只有Groovy,从Gradle 5.0开始官方推荐Kotlin DSL。
你想想看,现在Android开发都用Kotlin了,构建脚本还用Groovy,是不是有点割裂?
我拿一个简单的依赖配置来对比:
// Groovy DSL(.gradle 文件)
dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
implementation project(':mylibrary')
testImplementation 'junit:junit:4.13.2'
}
// Kotlin DSL(.gradle.kts 文件)
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation(project(":mylibrary"))
testImplementation("junit:junit:4.13.2")
}
区别很明显:
- Groovy用单引号,方法调用可以省略括号
- Kotlin DSL用双引号,方法调用必须带括号
- Kotlin DSL有类型安全,IDE提示更友好
我个人建议新项目直接用Kotlin DSL。虽然刚开始写的时候可能觉得括号多了点,但IDE的自动补全和编译时检查能帮你省不少事。我有个同事,用Groovy写错了依赖配置,运行时才报错,排查了半天……换成Kotlin DSL后,编译阶段就发现问题了。
第一个Gradle脚本
光说不练假把式。咱们写一个最简单的Gradle脚本,感受一下。
创建一个空目录,在里面新建 build.gradle.kts 文件:
// build.gradle.kts
tasks.register("hello") {
doLast {
println("Hello, Gradle!")
println("当前项目路径: ${project.projectDir}")
println("Gradle版本: ${project.gradle.gradleVersion}")
}
}
tasks.register("printTime") {
doLast {
println("构建时间: ${java.time.LocalDateTime.now()}")
}
}
// 给hello任务添加依赖
tasks.named("hello") {
dependsOn("printTime")
}
然后在终端执行:
./gradlew hello
你会看到输出:
> Task :printTime
构建时间: 2025-01-15T14:30:25.123
> Task :hello
Hello, Gradle!
当前项目路径: /Users/yourname/yourproject
Gradle版本: 8.4
这个例子虽然简单,但包含了Gradle的核心概念:
- Task —— 构建的最小执行单元
- doLast —— Task执行时的动作
- dependsOn —— Task之间的依赖关系
- project —— 当前项目的上下文对象
你可能会问:「这跟Android开发有什么关系?」
关系大了去了。Android的编译、打包、签名、混淆,本质上都是一系列Task的组合。你平时点的那个「Run」按钮,背后就是Gradle在调度几十个Task。
好了,这一章的内容就到这里。Gradle的入门概念、与Maven/Ant的对比、Wrapper的作用、DSL的选择,以及第一个脚本,咱们都过了一遍。接下来,你可以打开Android Studio,看看项目里的build.gradle.kts文件,试着理解每一行在干什么。相信我,当你开始「读懂」构建脚本的时候,你对Android项目的掌控力会上一个台阶。
公众号:蓝海资料掘金营,微信deep3321