学习总结#Gradle#自动化构建,Gradle与它的前辈们

467 阅读8分钟

前言

本篇文章介绍自动化构建概念以及相关工具,简单介绍AntIvyMaven,以及我们的主角 Gradle。读完这篇文章,你会了解一小段关于项目构建的发展历史,完善对项目构建的认知,以及为什么会出现GradleGradle能做什么。如果你觉得这些都已经了解了,那么可以直接去 Gradle官网 学习更多知识~

本篇文章结合自己的认知,总结《实战Gradle》1-2章的理论内容,如有不当或者过时、可优化的地方,麻烦指正,谢谢~。

自动化构建

在很久以前,人们打包项目都是手动的,通过一些特定的步骤最终产生用来运行的程序包,后来,自动化构建出现了,它极大地提升了生产效率。

它的优点有:

  • 过程自动化,一键调用,不易出错且可重复利用
  • 优秀的自动化构建,可以脱离机器的限定,可在任何时间、任何机器上运行。

项目自动化的类型大致分为以下几种:

  • 按需构建:执行一部分预定义的构建过程(比如:编译源码、移动文件、组装软件)。一般会使用版本控制系统(VCS: Version Control System)来管理构建定义的版本源码文件
  • 触发构建:由一次代码提交触发构建。通常敏捷开发中都会这么做。
  • 预定构建:在预定时间下进行构建。比如每天凌晨5点进行构建,一般用于生成报告或者一些文件。

触发构建与预定构建通常也叫做持续集成(CI: Countinuous Integration)

构建工具

构建工具与任务

你可能会有一个问题:一个shell脚本就可以做到自动化构建了,为什么要专门定义一个工具?

首先,一个shell脚本确实可以实现一个可重复利用、稳定可靠的构建。但是,它的可移植性不强,我们还是需要一个通用的工具,能在各个系统上运行。

这个工具是什么样的呢?它是一个可编程的工具,能够让你定义有序的任务去实现自动化需求。有序任务是什么样的呢,看下面这个例子:

在数据结构定义中,这是一个有向非循环图,它包含两个元素:

  • 节点:一个工作单元(只能被执行一次)
  • 有向边:表示节点的关系(这里表示依赖关系,比如上图中步骤2依赖于步骤1)

构建工具的基本组成元素

  • 构建文件:它包含了构建所需的外部信息以及外部依赖。
  • 构建的输入和输出:比如将源代码作为输入,输出结果为可交付的软件
  • 构建引擎:用于处理构建文件。
  • 依赖管理器:比如在build文件中声明的依赖定义,从工件仓库(本地文件系统、FTP、远程仓库等)中解析获取(比如jar文件),并使用在项目中。

Java的构建工具

构建工具一般都是可编程的工具(强调一下~),那么Java中常见的构建工具有哪种呢,下面介绍最流行的两种。

Apache Ant

Ant的基本编程元素有tasktargetproject,使用XML编写。

  • task:一段可执行的代码。
  • targettask集合,target可以依赖target
  • project:顶级元素,包含一个或多个target

Ant的优点是灵活性高,你可以随意定义task,再组装成target,并规定task之间的依赖。但是Ant有以下缺点:

  • 正因为这种自由性,并且没有统一的指导规范,导致Ant在面对复杂逻辑的时候难以维护,XML也会过于臃肿。
  • 没有暴露任何API可以使用。
  • 没有文件依赖管理系统(在没有Ivy的情况下难以管理外部依赖)

Apache Maven

Maven在如今的后台项目中经常见到,它算是站在Ant的肩膀上出现的,鉴于Ant的一些缺点,Maven做了改进。

设置默认值(基于约定犹豫配置的思想)

Maven给项目配置提供了默认值,以减少XML的臃肿,对,Maven也是使用XML编写的,如果你都接受Maven的默认值,你的配置文件只需要很少的行数;

构建生命周期

Maven同时也引入了构建生命周期的思想,规定了构建过程中必要步骤:

  • 编译源代码
  • 运行单元测试和集成测试
  • 组装文件(例如jar文件)
  • 将文件部署到本地仓库
  • 将文件发布到远程仓库

以上过程在Maven构建的时候会有序地执行,这些既有约定给了Maven规范性,不像Ant的构建文件会难以阅读,但同时也造成了Maven的局限性。下图是Maven重要的构建生命周期阶段,也是一些我们常用的命令:

依赖管理

Ant是没有依赖管理的,但是Maven有。Maven CentralJava社区中最流行的二进制仓库。(在提供依赖管理的同时,还提供了项目的多模块管理

Maven插件

提供很多插件,如果你想打破Maven的一些已有约定,就要使用Mojo编写自定义插件,但是在Maven中写插件是累赘且非常复杂的。


Gradle

“让不可能成为可能,让可能变得简单,让简单变得优雅”——Gradle座右铭


面对日益复杂的软件工程构建需求,Maven有如下缺点:

  • 因需要遵循它既有的约定,所以无法满足项目构建的灵活性需求;
  • 其使用的XML语言并不具有很强的表达性,难以定义复杂的定制逻辑;
  • 面对多语言编程构建的需求更加多样化,比如JavaSript需要被合并、压缩,服务器代码需要被编译、打包和部署,Maven也经不够给力了。

此时 Gradle 应运而生,它有以下优点

  • 基于JVM的构建工具,可以使用 GroovyKotlin 进行编写。可以描述非常复杂的逻辑。
  • 强大的API系统。暴露生命周期方法,高度自定义,以及提供了两个方便使用的配置模块(开箱即用):repositories & dependencies,可以定义依赖以及远程仓库。并且还有灵活的命令行API
  • 灵活的约定。遵循基于约定的构建方式,开发人员并不需要知道它是怎么工作的,只需要把精力集中在配置上。(当年小看Gradle的原因原来就是它的设计太好了嘤嘤嘤......)
  • 强大的依赖管理系统Gradle有自己的一套可配置、可靠的和有效的依赖管理方案。
  • 强大的插件系统。插件实现起来简单,并且可以让你完全访问GradleAPI,而且可以像其他软件一样编写、测试和发布。
  • 可以与其他构建工具集成。他能完美兼容AntIvyMaven,可以让你在感受Gradle特性的同时,小步地迁移。(这句话好优雅)
  • 可拓展的构建。支持增量构建、部分构建,而不是直接执行clean工作,使构建更迅速。
  • 多项目构建。可以模块化项目,组装多项目构建。
  • 多语言构建。不仅可以构建Java项目,还能构建WebC++项目等。

并且Gradle基于 Apache License 2.0 在 Github上开源,拥有非常活跃的 社区。 还有一些额外特性,比如 Gradle包装器,丰富的命令行接口,驼峰缩写调用(比如runMyAwesomeTesk可以使用rMAT命令进行调用)等等,并且,它是Android的官方构建语言。

如果你要开始Gradle的学习,我更建议从 官网 下手,毕竟官网都是最新资料

安装Gradle

安装过程很简单,我使用的是Windows环境,下载→解压→配置环境变量,再命令行验证一下:

运行Gradle脚本

每个Gradle构建都是以一个脚本开始的,当运行命令行命令的时候,Gradle会默认读取当前目录下的build.gradle文件(找不到则会报错)。

接下来写一个简单的 hello world 的例子。在D盘下创建test目录,在该目录下创建build.gradle文件,写入如下代码并运行:

.gradle为自动生成的文件;-q代表quiet,只输出该task相关的信息;hellotask的名称。看到这里,你的Gradle已经入门啦,我们再看一个例子,修改原来的代码为:

// 创建1个task
task startSession {
 chant()
}

// 定义方法
def chant() {
 ant.echo(message: 'Repeat...')
}

// 创建3个task
3.times {
 task "myTask$it" {
  println "Gradle Task --- $it"
 }
}

// 规定依赖
myTask0.dependsOn startSession
myTask2.dependsOn myTask0, myTask1
task groupTherapy(dependsOn: myTask2)

接下来执行所有task:

上图最前面是输出结果,下面将所有task都分类列出,可以看到我们定义的task与系统自带task

现在,你对Gradle应该有一定的认识了,如果想学习更多,请到官网学习吧~

补充

发现很多写Android的童鞋还不知道使用Maven库,这里补充下,一般大家可以到MavenRepository上去寻找自己想要的库,举个例子,我想要xml转换的相关库,我找到了JAXB的库:

我们可以看到有很多相关的构建工具的引用,不仅是Maven,还有前面提到的Ivy,剩下的大家有兴趣可以去研究研究。最后我们复制Gradle下面的代码放到项目中,就能愉快地使用啦~