首页 Android构建工具Gradle解析
文章
取消

Android构建工具Gradle解析

Gradle 是一个开源的自动化构建工具,其核心是基于 Java 实现,可以把它看成一个轻量级的 Java 应用,可以使用 Groovy 或 Kotlin 来编写脚本,简化了开发时对项目构建要做的配置,使用更加灵活和强大。

配置文件

build.gradle

该文件是项目构建文件,每个工程都有一个build.gradle文件,它在配置阶段执行,并创建相应工程的Project对象,执行的代码可以直接调用该对象提供的方法或者属性。

settings.gradle

该文件是在初始化阶段执行,创建Setting对象,在执行脚本时可调用此对象方法,它决定了哪些模块参与构建过程。

基本概念

项目:每个 build.gradle 都是一个项目对象,每一次 gradle 构建都至少包含一个项目,每个项目中都有各自的任务。

任务/task:任务定义在构建脚本中,包含一系列的动作,类似于一个方法,比如 clean 任务:

1
2
3
task clean(type: Delete) {
    delete rootProject.buildDir
}

声明周期

如上图所示,共分为三个阶段:

1. 初始化

Gradle支持单项目和多项目构建。在初始化阶段,执行settings.gradle脚本,Gradle读取include信息,并 确定哪些项目将参与构建,并为每个工程创建一个与之对应的Project 对象,最终形成一个项目层次结构。

2. 配置

配置阶段,执行每个工程的 build.gradle 文件,完成Project的配置,并且构造出Task任务依赖的一个有向无环图DAG,以供执行阶段按照依赖顺序执行,并对任务做一些初始化配置。

3. 执行

运行阶段,Gradle 根据配置阶段创建和配置的要执行的任务子集,执行任务。

Task

语法:

1
2
3
4
5
6
7
8
9
10
11
task <任务名称> {
    // 代码块
    
    doFirst {
        // 执行
    }
    
    doLast {
        
    }
}

上面代码中,定义在task中的代码块只是设置了任务的配置,在配置阶段执行,那么想要在执行阶段添加动作action,就可以在doFirst和doLast方法中添加。

依赖

task A(dependsOn:[B]){ .. } 表示任务 A 依赖于任务 B,那么 B 执行在 A 之前。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
task A{
    println "test A"
    doLast{
        println "test A-doLast"
    }
}
//这里表示任务B依赖任务A,在A执行后才会执行B
task B(dependsOn:[A]){
    println "test B"
    doLast{
        println "test B-doLast"
    }
}

// 执行./gradlew B
> Configure project :app
test A
test B

> Task :app:A
test A-doLast

> Task :app:B
test B-doLast

插件

自定义 Gradle 插件有三种方式:

  • 构建脚本

可以直接在构建脚本中包含插件的源代码。这样做的好处是插件可以自动编译并包含在构建脚本的类路径中,而不需要您做任何事情。然而,插件只能在定义它的构建脚本之内可见,不能在其他脚本中复用插件。

  • buildSrc

可以将插件的源代码放在rootProjectDir/buildSrc/src/main/java目录(或rootProjectDir/buildSrc/src/main/groovyrootProjectDir/buildSrc/src/main/kotlin中,具体取决于你使用的语言)。 Gradle将负责编译插件,并使其在构建脚本的类路径中可用。 该插件对整个项目里的每个构建脚本都是可见的, 但是,它在项目外部不可见,因此不能其他项目中复用该插件。

  • 独立项目

可以为插件创建一个单独的项目,将项目打包成一个JAR包,然后可以在多个项目中复用。

实践

执行gradle init命令,按照下面步骤一步一步选择配置,最终创建完项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Starting a Gradle Daemon (subsequent builds will be faster)

Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 4

Select implementation language:
  1: Groovy
  2: Java
  3: Kotlin
Enter selection (default: Java) [1..3] 1

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1

Project name (default: gradle_plugin): com.yuxingxin.plugintest
Source package (default: com.yuxingxin.plugintest):

> Task :init
Get more help with your project: https://docs.gradle.org/7.2/userguide/custom_plugins.html

BUILD SUCCESSFUL in 35s
2 actionable tasks: 2 executed

紧接着创建一个名为Greeting的任务,目的是向该插件的项目注册一个这样的任务,它做的事情就是在doLast时候打印一句话。

1
2
3
4
5
6
7
8
9
10
public class HelloPlugin implements Plugin<Project> {
    public void apply(Project project) {
        // Register a task
        project.tasks.register("greeting") {
            doLast {
                println("Hello from plugin 'com.yuxingxin.plugintest.greeting'")
            }
        }
    }
}

发布该插件需要借助Maven Publish Plugin插件,首先在build.gradle中应用:

1
2
3
4
plugins {
    ...
    id 'maven-publish'
}

然后定义插件的发布信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
publishing {
    publications {
        // 这里的 hello 可以任意命名
        hello(MavenPublication) {
            // 插件的组ID,建议设置为插件的包名
            groupId = 'com.yuxingxin.plugintest'
            // 插件ID
            artifactId = 'greeting'
            version = '1.0.0'
            // 组件类型,我们的插件其实就是Java组件
            from components.java
        }
    }
    // 不指定repositories会默认发布在.m2/repository/目录下
    repositories {
        maven {
            // 这里发布到自己项目,$rootDir 表示你项目的根目录
            url = "$rootDir/repo"
        }
    }
}

然后就可以接入自己的项目使用了。

本文由作者按照 CC BY 4.0 进行授权

基于Hacker News的内容热度推荐算法

Android构建流程分析