0%

Gradle学习(一):初识Gradle

Gradle是一套基于JVM的新一代自动化构建工具。早期,构建只有编译和打包的简单需求。但是现代软件开发的模式改变了,大多数项目都包含有多而杂的技术栈、混合的多种编程语言,并且使用多种测试策略。随着敏捷实践的崛起,构建不得不更早地支持代码集成,以及频繁和简单地交付软件到测试和产品环境。Gradle便是在这一背景下衍生出来的。

Gradle 的座右铭:

    “让不可能成为可能,让可能变得简单,让简单变得优雅”。

1.认识Gradle

Gradle是基于JVM构建工具的新一代版本,它从现有的构建工具如Ant和Maven中学到了许多东西,并且把它们的最优思想提升到更高层次。遵循基于约定的构建方式,Gradle可以用一种声明式的方式为你的问题领域建模,它使用一种强大的且具有表达性的基于Groovy的领域特定语言(DSL),而不是XML。因为Gradle是基于JVM的,它允许你使用自己最喜欢的Java或者Groovy语言来编写定制逻辑。

1.1 Gradle的优点

  • 表达性的DSL:Gradle构建脚本采用基于Groovy的DSL领域特定语言,而不是采用传统的XML文件,相比Maven等构建系统更加简洁易读;
  • 基于JVM:Groovy语言基于JVM,这使得Gradle支持Java/Kotlin代码编译构建脚本,你不必成为Groovy的专家才能开始写脚本,降低了Gradle的学习难度。
  • 增量性构建:大型项目可能拥有上百个模块,构建和测试少量代码的改变会消耗很多时间。Gradle支持指定任务的输入和输出进行增量性构建。它准确的找出哪些任务需要跳过,哪些需要构建或者部分构建。同样的思想也应用到多模块项目中,叫做部分构建。
  • 自定义Task:可以构建自己的任务,然后挂接到Gradle构建的生命周期中去。

1.2 Gradle工程的基本结构

├── a-subproject
│   └── build.gradle
├── build.gradle
├── settings.gradle
├── gradle.properties
├── local.properties
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
  • settings.gradle文件:确定哪些模块参与构建;
  • 项目级build.gradle文件:定义子模块公共的配置参数;
  • 模块级build.gradle文件:用于定义子模块的配置参数,它可以覆盖项目级build.gradle中定义的配置;
  • gradle/wrapper:负责自动下载安装项目所需的Gradle环境的脚本;
  • gradle.properties:项目级gradle配置项,回覆盖全局的配置项;
  • local.properties:项目的私有属性配置,如SDK安装目录,一般不会被加入版本控制;
  • gradlew和gradlew.bat:用来执行构建任务的脚本。命令行gradlew使用Gradle Wrapperz执行构建;命令行gradle使用系统环境变量定义的Gradle环境变量进行构建。

2 Gradle构建的生命周期

Gradle将构建划分为三个阶段:初始化阶段(Initialization)、配置阶段(Configuration)、执行阶段(Execution)。通过理解构建的生命周期,可以知道脚本中每个代码单元的执行时机。

2.1 初始化阶段

Gradle支持单模块和多模块构建。因此初始化阶段需要明确哪些模块将参与构建。主要包含以下几步:

  • 解析根目录下的settings.gradle文件,并实例化一个settings对象;

  • 执行settings.gradle脚本,settings.gradle中的代码会在初始化阶段执行;

  • 生成Project对象。Gradle会为settings.gradleinclude的每个模块实例化一个Project对象。

2.2 配置阶段

配置阶段,将执行参与构建的每个模块的build.gradle,已完成Project的配置。主要包含以下几步:

  • 下载依赖和插件;

  • 执行build.gradle中的代码;

  • 根据task的依赖关系构造一个有向无环图(Directed Acyclic Graph),以便在执行阶段按照依赖关系执行task。

2.3 执行阶段

配置阶段构造了task有向无环图,执行阶段会按照依赖关系执行task。

注意:
Task配置代码在配置阶段执行,Task动作在执行阶段执行;
即使是执行单一一个Task,整个工程的初始化阶段和配置阶段也会执行,这是为了支持在执行中访问Gradle构建模型中的任何一部分。

3 生命周期的监听

3.1 初始化阶段监听

初始化阶段包含解析settings.gradle文件、获取setting实例、创建Project实例。可以使用以下代码监听:

//settings配置完毕
this.gradle.settingsEvaluated {
    println "settings Evaluated"
}

//所有Project对象创建完成
this.gradle.projectsLoaded {
    println "projects Loaded"
}

3.2 配置阶段监听

Project接口提供了监听当前Project配置阶段执行的方法:

//执行build.gradle之前
project.beforeEvaluate {
    ...
}

//执行build.gradle之后
project.afterEvaluate {
    ...
}

此外,Gradle接口也提供了配置阶段的监听:

//执行build.gradle之前
gradle.beforeProject {
    
}

//执行build.gradle之后
gradle.afterProject {
    
}

//与上边的方法等价
gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {
    @Override
    void beforeEvaluate(Project project) {

    }

    @Override
    void afterEvaluate(Project project, ProjectState projectState) {

    }
})

//监听依赖关系解析完毕
gradle.addListener(new DependencyResolutionListener() {
    @Override
    void beforeResolve(ResolvableDependencies resolvableDependencies) {

    }

    @Override
    void afterResolve(ResolvableDependencies resolvableDependencies) {

    }
})

//task 有向无环图构造完毕
gradle.taskGraph.whenReady {
    
}

//所有的Project的build.gradle执行完毕
gradle.projectsEvaluated {
    
}

3.3 执行阶段监听

//监听task执行
gradle.addListener(new TaskExecutionListener() {
    
    //执行前
    @Override
    void beforeExecute(Task task) {

    }

    //执行后
    @Override
    void afterExecute(Task task, TaskState taskState) {

    }
})

//监听action列表执行
gradle.addListener(new TaskActionListener() {
    
    //开始执行Action列表之前,回调时机略晚于TaskExecutionListener#beforeExecute
    @Override
    void beforeActions(Task task) {

    }

    //执行Action列表之后,回调时机略早于TaskExecutionListener#afterExecute
    @Override
    void afterActions(Task task) {

    }
})

监听构建结束:

gradle.buildFinished {
    
}