本文默认读者使用 macOShtml
以我本身为例,刚开始接触 Android 开发的时候,只是对 Java 开发有一些了解,对于 Android 开发的整个生态和技术栈只有一个模糊的认知。 缺少对 Gradle 的认知,在初级开发阶段可能勉强能够应付,只须要知道如何添加第三方依赖,如何调整 android block 中的配置基本上就够了,可是随着项目结构愈来愈复杂,默认提供的构建过程渐渐不能知足开发的需求,此时就要求开发者对 Gradle 的构建过程和原理有更深刻的了解,便于自定义个性化的构建过程。java
在阅读完 《Gradle In Action》后,我发现 Android 工程的构建过程彷佛再也不那么神秘了。 本文但愿能从宏观的角度带刚接触 Android 开发不久的同窗认识一下 Gradle,若是对 Gradle 工做原理感兴趣,但愿可以更加深刻了解,建议阅读 《Gradle In Action》 这本书。android
随着项目规模增大,软件工程师须要考虑的事情会愈来愈多。成功构建并运行一个项目再也不像单文件的 HelloWorld 同样简单。随着持续集成思想的普及,一次成功的构建可能分为 checkStyle,Lint,编译,单元测试,集成测试,代码裁剪,代码混淆,打包部署等多个步骤。若是项目中引用了第三方 lib,那么第三方 lib 会有版本迭代,甚至多个第三方 lib 可能又依赖了不一样版本的同一个第三方 lib,形成依赖版本冲突,事情会愈来愈复杂。咱们须要使每个 Commit 老是能构建出彻底相同的结果,Git 对于二进制文件的版本管理又不是那么驾轻就熟,手动构建经常会引入人为变数致使构建出错。因此构建过程自动化迫在眉睫。git
Google 基于 Gradle 经过 Android Gradle Plugin 提供了自动化构建的工具,对开发者隐藏了大量的繁琐的构建过程,暴露一些可被开发者配置的属性,大大的简化了 Android 项目管理的复杂度的同时又不失灵活性。web
在这里列举的构建工具不止能够用来构建 Java 相关的项目。只要能表达出构建步骤,就可使用这些工具来进行项目构建。好比,你可使用 Gradle 来构建一个 iOS 的项目。api
The Wrapper is a script that invokes a declared version of Gradle, downloading it beforehand if necessary. As a result, developers can get up and running with a Gradle project quickly without having to follow manual installation processes saving your company time and money.bash
构建工具也是须要版本迭代的,一个大的版本迭代可能不会提供向前的兼容性,也就是说,在 A 机器上和 B 机器上装了两个不一样版本的 Gradle,结果可能致使同一个项目,在 A 的机器上能够成功构建,而在 B 的机器上会构建失败。 为了不这个问题,保证每一个 Commit 总能构建出彻底相同的结果。Gradle 提供了 Gradle Wrapper,经过 Wrapper 运行 Gradle Task 的时候,会先检查 gradle-wrapper.properties 中指定的位置下,指定版本的 Gradle 是否安装,若是已经安装,则将该 Gradle Task 交给 Gradle 处理。若是没有安装,则先下载安装指定版本的 Gradle,而后再将 Gradle Task 交给 Gradle 处理。 gradlew 是一个 script,是 Gradle Wrapper 的入口,Windows 下是 gradlew.bat。 gradle-wrapper.jar 提供了 Gradlew Wrapper 的核心功能。oracle
目录结构以下图: app
以下图所示是一个典型的使用 Gradle 进行构建的 Android 工程。 工程中包含两个 Project:
gradlew projects
复制代码
gradlew 是入口 Script, projects 其实是 Gradle 一个内置的 Task。 关于 Task 的概念,下面再解释。 运行上面的命令,结果以下图所示,能够看到,通常咱们开发时修改 **app **只是一个子项目,RootProject 其实是 app 的上级目录中的 TutorialAndroid。
Gradle 的构建过程分为如下几个阶段: initialization -> configuration -> execution
A Task represents a single atomic piece of work for a build, such as compiling classes or generating javadoc.
A Task is made up of a sequence of Action objects. When the task is executed, each of the actions is executed in turn, by calling Action.execute(T). You can add actions to a task by calling Task.doFirst(org.gradle.api.Action) or Task.doLast(org.gradle.api.Action).
// 定义好 Task 以后,就能够经过 `gradlew simpleTask` 来运行指定的 Task
task simpleTask {
doLast {
println "This is a simple task."
}
}
复制代码
Gradle determines the subset of the tasks, created and configured during the configuration phase, to be executed. The subset is determined by the task name arguments passed to the gradle command and the current directory.
当一个 Project 的 Task 愈来愈复杂,或者多个项目都须要共用同一个 Task 的时候,为了提升代码复用性,能够编写 Plugin 将建立 Task 等逻辑封装起来。
提升了代码复用性的同时,还须要提供足够的灵活性。Plugin 能够经过 Extension 暴露一些可配置的属性。这里先不讲,超纲了。
以上就是 Gradle 的工做过程。
使用 Proxy
在国内特殊的网络环境,能够经过设置 Proxy 或 Repo Mirror 的方式来提升下载依赖的 Library 的速度。
阿里提供的镜像 maven.aliyun.com/mvn/view Gradle 使用 Java 的 Networking Properties 读取 Proxy 参数。可供设置的参数参考如下文档。
注意你的电脑中运行了多少 Gradle Daemon
Gradle 提供了 Daemon 机制来提升构建速度,可是 Gradle Daemon 的复用是有条件的。 若是恰巧给 Gradle Daemon 设置了一个比较大的 maximum heap size, 可能在开发的过程当中,多个 Daemon 会占用过多的内存,影响电脑运行速度。除了前面给出的条件,还有两点是以前开发过程当中遇到过的:
《Gradle In Action》 -- Benjamin Muschko
@Eric