文章目录
- 1. JVM构建工具的发展
- 1.1 背景
- 1.2 Ant - Java 早期构建工具
- 1.3 Maven - Ant 的升级版
- 1.3 Gant - IDEA 官方的构建工具
- 1.4 Gradle - JVM集大成构建工具
- 2. 为什么学习 Gradle?
- 3. 学习提纲
- 参考
1. JVM构建工具的发展
1.1 背景
我们平时在 IDE 上写了很多代码,然后直接 Shift+F10 让它运行在了平台环境(Android、Windows、iOS)上。这是因为 IDE 内置了编译、打包的能力,能够将代码编译成对应平台能够直接识别和运行的二进制文件。
所以我们并不用关心 IDE 底层到底是如何编译代码的,只关心代码能不能在平台上按预期跑,有没有Bug,把注意力集中在应用层的代码逻辑实现上。
但假如你写的代码要放在用户的手机上用,你总不能让用户的手机连着你的电脑吧?亦或是你做了一个很吊的功能,别人想用这个功能,你乐意接受,但却不想将源码暴露出来,这该如何是好呢?
答案是:将代码以某种形式(二进制文件)上传到服务器上,用户下载后可以安装到手机上运行;别人也可以引用这个代码能力,同时查看不到所有的源码。
比如我们所熟知的 .dex
(Andorid)、.class
(Java)、.pyc
(python)都是经转化后能够被特定平台所识别的二进制文件。
我们一般把:
- 代码转化成二进制文件的行为称作: 编译(Compile)
- 将这些二进制文件优化成能被特定平台使用的文件的行为称作:打包(Package)
- 将这些文件上传到服务器的行为称作:发布 / 部署(Publish)
虽然用了短短几个词进行概括,但在底层则是做了一系列的事情,例如 代码编译
、依赖管理
、签名
、资源编译
、混淆
、对齐
等等操作。每些操作都需要依赖独特的工具,很明显,我们这些上层开发肯定是不会参与到这一流程中的,而是交给一套脚本工具,让脚本工具去集成 / 组合这些操作,然后按照顺序执行命令,实现自动化一条龙服务。我们平时写完代码后,点击“运行”其实就是让这套脚本工具开始运作。
如下图所示,从应用代码到生成 Apk 需要经历多个步骤,为了减少人工成本,需要自动化地去顺序执行这些操作,这就是构建脚本存在的意义。
在我们的 Java 领域上,有这些脚本工具和配套工具:
Ant
Maven
Gant
Gradle
下面一一来介绍它们。
1.2 Ant - Java 早期构建工具
Ant
是由 Apache 公司开发的用于 Java 编译、测试、部署的自动化工具。 其脚本语言是 XML
。
它内置了 javac
、 java
、创建 / 复制目录等功能,所以可以直接编译我们的 Java 代码生成实际项目。
每个脚本工具都会有一个默认的构建代码的文件,对于 Ant
来说,叫做:build.xml
,它长这个样子:
<?xml version="1.0" ?>
<project name="Hello World" default="execute">
<target name="init">
<mkdir dir="build/classes"/>
<mkdir dir="dist"/>
</target>
<target name="compile" depends="init">
<javac srcdir="src" destdir="build/classes"/>
</target>
<target name="compress" depends="compile">
<jar destfile="dist/HelloWorld.jar" basedir="build/classes" />
</target>
<target name="execute" depends="compile">
<java classname="HelloWorld" classpath="build/classes"/>
</target>
</project>
它有几个标签,介绍其中几个重要的标签:
-
<project>
:生成文件的根元素,表示一个工程 -
<target>
: project的子元素,表示一个任务; 一个project中可以定义多个target元素,表示多个任务 -
<jar>
:打包成 jar 包,destifile
为打包之后的名称,basedir
则为需要打包的 java 文件目录 -
<java>
:运行 java 类,classname
指定运行类的名称,classpath
指定运行类所在的目录
Ant
是十分著名的 Java 自动化脚本工具,它的出现是为了解决早期的 Linux
的脚本工具 Make
的痛点,自发布以来,深受广大 Java 开发的青睐。但是 Ant 也有一些局限性和缺点,比如:
-
Ant
很难管理依赖,一般都要配合Ivy
(一种管理项目依赖的工具) 使用; -
Ant
无法获取运行时的信息; -
XML
作为脚本语言有一定的局限性,例如构建逻辑复杂时,XML
的代码将会很长,维护成本较大; -
Ant
并没有为 Java 的自动化构建提供一个标准流程,其默认脚本文件一无所有,非常的灵活,需要开发者手动定制每个阶段的构建,这会导致大伙不清楚怎么样写脚本才是标准的,为此而苦恼。 - …
1.3 Maven - Ant 的升级版
Maven
继承了 Ant
的项目构建功能,同样使用 XML
作为脚本语言,但它解决了很多 Ant
的痛点,例如:
- 它解决
Ant
过于灵活(开发需要从头到尾编写一份) 的问题,提供的默认脚本文件pom.xml
里面帮我们定好了一套构建流程,我们在其给定好的标签里发挥就行。使得开发者不必在为“什么才是标准的构建流程代码”而苦恼了。
<project>
<!-- Maven 2.X 版本的 pom文件 ,model的版本总是 4.0.0 -->
<modelVersion>4.0.0</modelVersion>
<!-- 本项目的坐标,表示项目标识的一组值信息 -->
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0</version>
<!-- 库依赖 -->
<dependencies>
<dependency>
<!-- 依赖库的坐标信息 -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<!-- 此依赖项仅用于运行和编译测试 -->
<scope>test</scope>
</dependency>
</dependencies>
</project>
- 它解决了
Ant
需要依赖Ivy
工具的问题。Maven
提供公共的中央仓库,即脚本工具自身提供依赖管理能力。
Maven从一个或多个代码仓库(例如Maven 2Central Repository
)动态地下载 Java 库与 Maven 插件,并将其存储在本地缓存区中
1.3 Gant - IDEA 官方的构建工具
Gant
也是一个基于 Ant
的构建工具,但这一次它不再使用 XML
做为脚本语言,而是使用 Groovy
语言做为脚本语言。
IDEA 默认支持 Gant
,它能识别 .gant
结尾的文件, build.gant
就是其默认构建脚本文件,等同于 build.xml
。可以看下这个文件:
Ant.echo(message : 'running build.gant')
Ant.property(file : 'build.properties')
def antProperty = Ant.project.properties
target(hello : 'say hello target') {
depends(init)
echo(message : antProperty.'echo.msg')
}
setDefaultTarget(hello)
Gant 和 Ant 的关系,就像是 Retrofit 和 OkHttp 的关系那样,通过使用 Groovy 语言来调用 Ant 的能力。不过 Groovy
语言相较于 XML
能够在写出复杂逻辑的构建代码时,提供不错的可读性,很多场景完全可以使用 Gant 来替代 Ant。
1.4 Gradle - JVM集大成构建工具
终于来到我们的主角:Gradle
,它拥有上述几个脚本工具所具有的优点:
- 使用
Groovy
作为脚本语言,在编写复杂构建逻辑时,能保持优良的可读性和重用性,并且很灵活,不像XML
那样受限于只能描述数据而非流程的特性; - Gradle 是 Android 官方的构建工具,如今还能支持使用
Kotlin
来编写,对 Android 开发者来说非常之友好; - 强大的依赖管理,它能将依赖的库下载到电脑缓存中,被项目引用。即使跨平台跨机器,也能生成相同的库;
-
Gradle Wrapper
可以帮我们下载和管理 Gradle 版本,因为 Gradle 有多个版本,不同项目可能使用的是不同版本的Gradle,这个时候为了能够运行别人的项目,可以通过Gradle Wrapper
来了解别人的构建版本,然后通过下载或修改使之能够运行在我们的电脑上; - …
它的默认脚本工具是 build.gradle
,长这样:
plugins {
id 'com.android.application'
}
android {
defaultConfig {
applicationId "com.example.gradle_demo"
minSdk 21
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
}
总之,Gradle 已经成为 JVM 上首选构建工具,作为一名 Android 程序员,我们甚至不用学习 Groovy
,而是直接使用 Kotlin
来学习就好了。
2. 为什么学习 Gradle?
若要成为一名优秀的 Android 开发者,不仅要对应用层、Framework层有深刻的理解,还需掌握 Gradle
,深入打包、发布流程。
Gradle
是 Android 开发息息相关的一门技术,由于 IDE 高度集成了 Gradle,大部分人平时基本和 Gradle 打不上交道,很多应用层开发者对这方面的认知较为浅薄,知识点零散。
通过学习 Gradle,除了了解编译、打包的知识,我们还能够进阶:因为很多 Android 技术都会涉及到 Gradle, 例如 自动化、热修复、组件化、系统构建等,如果不会 Gradle,那势必也学不好这些技术。
3. 学习提纲
这里我根据整理来的知识,罗列一下学习清单:
主要不求过于深入,但求覆盖所有基础知识点。
参考
Gradle - Wiki如何通俗理解 Gradle? - 知乎Gradle核心思想(一)为什么现在要用Gradle?