0x1、初识Gradle
1. 自动化构建工具
**Gradle
**的定义如下:
使用纯Java编写,基于Ant、Maven概念开源的
自动化构建工具
,专注于灵活性和性能,构建脚本
摒弃了基于XML的繁琐配置,采用Groovy
或Kotlin
的特定领域语言(DSL)
来编写。
拆词开始:
- 构建 → 将源码生成可执行程序的过程;
- 自动化 → 用机器代替手工的一些工作;
构建在Android中的体现就是:编译源码 → 生成.apk可执行文件,在 Android官网 中有这样一个构建流程图:
简析下流程:
- IDE将源代码转成dex,其他内容转换成编译后的资源;
- APK打包器将dex和编译后的资源整合成单个apk;
- 打包器使用zipalign工具对应用进行优化,为apk签名;
当然,这是高度抽象后的流程,实际的打包过程可要复杂得多:
- aapt命令 → 生成R.java文件;
- aidl命令 → 生成aidl对应的java文件;
- javac命令 → 编译java源文件生成class文件;
- dx.bat → class转换成class.dex文件
- ...等
想想如果每次打包apk,都要手工用各种命令、工具按顺序来打包,效率得有多低,碰上要打十几个渠道包的,打包仔直接原地去世!
Tips:不同应用市场可能有不同的统计需求,需要为每个应用市场发布一个安装包,这就是渠道包。
人是容易犯错的,特别是这种 手动介入的重复任务,把渠道标识弄乱打错包这类事情时有发生。
可以把这种流水线式重复构建的活写到一个脚本中(构建脚本
),每次打包,执行下这个脚本 自动化
打包即可,使得让开发仔可以心无旁骛地编写功能代码,以此提高开发效率。
构建脚本的内容就是按照构建流程,依次执行命令、调用工具,最后将生成的可执行文件输出到特定目录。
说到脚本,有些童鞋立马上头,准备Python、Bash一把梭,实际上大可不必。
开源的自动化构建工具
就很香,没必要重复造轮子,还得自己踩波坑~
2. Ant、Maven、Gradle的区别
Android 早期使用Eclipse作为IDE时,用的自动化构建工具 → Apache Ant
,Java编写、平台无关、基于任务链思想,采用XML作为构建脚本,文件默认是build.xml,基础配置模板如下:
<?xml version="1.0" encoding="UTF-8" ?> <project name="HelloWorld" default="run" basedir="."> <property name="src" value="src"/> <property name="dest" value="classes"/> <property name="jarfile" value="hello.jar"/> <target name="init"> <mkdir dir="${dest}"/> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${dest}"/> </target> <target name="build" depends="compile"> <jar jarfile="${jarfile}" basedir="${dest}"/> </target> <target name="test" depends="build"> <java classname="test.ant.HelloWorld" classpath="${hello_jar}"/> </target> <target name="clean"> <delete dir="${dest}" /> <delete file="${hello_jar}" /> </target> </project>
可以清晰地看到脚本中定义了五个Target,分别是:init、compile、build、test、clean,Target。
它们之间还通过depends定义依赖关系,以此形成了执行的先后顺序,执行build Target前会执行compile,而执行compile前又要init。
Ant 还支持自定义Target,但存在一个问题:没办法管理依赖
,项目依赖到第三方库,需要自己手动将 正确版本
的包拷贝到lib目录下,早期到处找各种jar包的场景依旧历历在目。
所以,带依赖库管理的 Apache Maven
来了,只需在工程管理文件中(pom.xml)标明需要的包及版本,构建时Maven会自动打包到工程中,示例如下:
<?xml version="1.0" encoding="utf-8"?> <project ...xmlns...> <groupId>cn.coderpig</groupId> <artifactId>Test</artifactId> <version>1.0.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.9.1</version> </dependency> </dependencies> </project>
定义了自己的包:cn.coderpig:Test:1.0.0-SNAPSHOT,工程依赖了:com.squareup.okhttp3:okhttp:4.9.1,Maven会自动把okhttp包打进来,没有的话还会自动到网上下载(远程仓库,可通过repository标签指定)。
Maven抛弃了Ant中通过Target定义任务的做法,采用 约定优于配置的思想
,抽象出一套满足大部分项目的 构建生命周期
:clean → default → site,要求用户 在给定的生命周期中
使用插件的方式去完成构建工作。
规范化好是好,但也带来一个问题:自定义构建需求实现麻烦
,没办法像Ant那样灵活。
还有一点,Ant和Maven都使用XML定义构建脚本,可读性及扩展性较差,在任务执行上较弱(不支持循环,条件判断麻烦等)。
所以,集Ant和Maven所长,功能更强大的 Gradle
来了:
- ① 抛弃繁琐的XML,采用Grovvy DSL或Kotlin DSL来编写构建脚本;
- ② 可以像Maven一样自动下jar包,即依赖管理;
- ③ 有默认标准的构建生命周期,也支持灵活的自定义任务等;
- ④ 构建级别支持从Ant、Maven的逐步迁移;
Tips:DSL(Domain Specific Language),特定领域语言,专注于 特定领域问题 的计算机语言,如SQL仅支持数据库相关操作,正则表达式只支持字符串的检索替换。以简洁的形式进行表达,直观易懂、使得读、调代码的成本得以降低,就是求精不求广。
简单小结下三者区别:
Ant支持自动化打包逻辑,Maven比它多了自动下jar包,规范了打包逻辑,反而不好定制。Gradle既能自动下jar包,又能自己写脚本,而且脚本写起来比Ant爽。
3. Gradle的下载配置
Gradle基于JVM,需要Java环境(1.8及以上版本),在 Gradle官网 下载对应版本Gradle,此处以6.1.1为例,有四种类型的包可供下载:
下载bin和all都可以,我习惯下后者,有时需要看下源码和文档,下载zip包后解压,配置下环境变量 GRADLE_HOME,Windows环境配置示例如下:
Path环境变量新增:
配置完后打开终端,键入:gradle -v 验证是否生效。
4. Gradle Wrapper
Android Studio默认使用 Gradle Wrapper
而不是直接使用 Gradle
,命令也是使用 gradlew
而不是 gradle
。
这个Gradle Wrapper就是对Gradle的一层封装,使得开发者无需关心项目Gradle的版本变化。
新建一个目录,键入下述命令:
gradle wrapper
生成文件目录结构如下:
├── .gradle ├── gradle │ └── wrapperwrapper | └── gradle-wrapper.jar // 用于下载所需Gradle; | └── gradle-wrapper.properties // 配置文件; ├── gradlew //Linux下的可执行脚本; └── gradlew.bat //Windows下的可执行脚本;
接着键入:gradlew build 编译,检查到配置文件中对应版本的Gradle本地没有时,会启动 wrapper进程
下载配置Gradle,完事后此进程会自动关闭。
gradle-wrapper.properties
配置文件内容如下:
Windows下指向:C:\Users\用户名.gradle 目录,打开可以看到下载各个版本的gradle:
封装一层还有个好处:在没有安装Gradle的机器上也可以使用Gradle构建项目,但有一点要注意:
每个Gradle版本对应一个Daemon进程,基本512M起步,电脑配置不佳 的情况下,应尽量避免多个版本的Gradle同时运行。建议:自己管理Gradle,即使用本地创建Gradle环境,AS的配置方法如下:
5. 构建脚本初体验
键入下述命令新建一个build.gradle文件然后编译:
touch build.gradle echo println("Hello Gradle!"); >> build.gradle gradlew
输出内容如下:
执行 gradle
时会从当前目录查找名为 build.gradle
或 build.gradle.kts
的文件并执行其中的内容。
除手动创建的方式外,还可以通过 gradle init
自动初始化不同类型的Project:
此处以Kotlin application工程为例,打开目录查看创建的文件:
可以看到build.gradle中添加了一些依赖,键入 gradlew build
编译下项目: