文章目录

  • 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 需要经历多个步骤,为了减少人工成本,需要自动化地去顺序执行这些操作,这就是构建脚本存在的意义

Android Gradle 学习笔记(一)概述_构建工具

在我们的 Java 领域上,有这些脚本工具和配套工具:

  • Ant
  • Maven
  • Gant
  • Gradle

下面一一来介绍它们。

1.2 Ant - Java 早期构建工具

Ant 是由 Apache 公司开发的用于 Java 编译、测试、部署的自动化工具。 其脚本语言是 XML

它内置了 javacjava、创建 / 复制目录等功能,所以可以直接编译我们的 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 的痛点,例如:

  1. 它解决 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>
  1. 它解决了 Ant 需要依赖 Ivy 工具的问题。 Maven 提供公共的中央仓库,即脚本工具自身提供依赖管理能力。
    Maven从一个或多个代码仓库(例如Maven 2 Central 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集大成构建工具

Android Gradle 学习笔记(一)概述_Gradle_02


终于来到我们的主角: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. 学习提纲

这里我根据整理来的知识,罗列一下学习清单:

Android Gradle 学习笔记(一)概述_java_03

主要不求过于深入,但求覆盖所有基础知识点。

参考

Gradle - Wiki如何通俗理解 Gradle? - 知乎Gradle核心思想(一)为什么现在要用Gradle?