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的核心工作流程可以概括为三个阶段:

  1. 初始化阶段——解析settings.gradle,确定哪些模块参与构建
  2. 配置阶段——执行每个模块的build.gradle,生成Task依赖图
  3. 执行阶段——按依赖顺序执行Task

下面这张图帮你快速理解Gradle的整体架构:

Gradle 核心架构图 初始化阶段 解析 settings.gradle 确定参与构建的模块 创建 Project 对象 配置阶段 执行 build.gradle 生成 Task 依赖图 配置所有 Task 执行阶段 按依赖顺序 执行 Task 生成产物 关键特性: • 基于 Groovy/Kotlin DSL,构建脚本就是代码 • 增量构建:只编译修改过的部分,大幅提升构建速度 • 依赖管理:自动下载和管理第三方库及其传递依赖 • 插件机制:Android插件、Kotlin插件等,扩展构建能力

Gradle vs Maven vs Ant

很多老项目还在用Maven或者Ant。我当年接手过一个用Ant构建的项目,那叫一个酸爽——依赖全靠手动下载,版本冲突全靠肉眼排查。后来迁移到Gradle,整个人都解脱了。

这三者的区别,我用一个表格给你说清楚:

对比维度 Ant Maven Gradle
构建脚本 XML,冗长 XML,约定大于配置 Groovy/Kotlin DSL,简洁灵活
依赖管理 无,手动管理 内置,支持传递依赖 内置,支持动态版本、依赖锁定
性能 一般 较慢,全量构建 快,增量构建+构建缓存
扩展性 差,自定义逻辑困难 一般,插件开发复杂 强,自定义Task和插件简单
Android支持 不原生支持 需额外配置 官方支持,Android插件
我的建议:新项目直接上Gradle,别犹豫。老项目如果是Maven,迁移成本也不高,Gradle兼容Maven仓库。至于Ant……能跑就别动了,但新功能别用Ant写了。

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后,编译阶段就发现问题了。

注意:Kotlin DSL的编译速度比Groovy慢一点,因为需要编译Kotlin代码。但这点时间跟构建总时间比起来,可以忽略不计。别因为这个理由拒绝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不是黑盒子,它就是一个可以编程的构建工具。你写的build.gradle,本质上就是告诉Gradle「先做什么,再做什么,用什么参数做」。理解了这一点,后面学自定义插件就水到渠成了。

好了,这一章的内容就到这里。Gradle的入门概念、与Maven/Ant的对比、Wrapper的作用、DSL的选择,以及第一个脚本,咱们都过了一遍。接下来,你可以打开Android Studio,看看项目里的build.gradle.kts文件,试着理解每一行在干什么。相信我,当你开始「读懂」构建脚本的时候,你对Android项目的掌控力会上一个台阶。


公众号:蓝海资料掘金营,微信deep3321