请通过以下方式下载本系列文章的Github示例代码:
git clone https://github.com/davenkin/gradle-learning.git
如果我们将Gradle的Task看作一个黑盒子,那么我们便可以抽象出输入和输出的概念,一个Task对输入进行操作,然后产生输出。比如,在使用java插件编译源代码时,输入即为Java源文件,输出则为class文件。如果多次执行一个Task时的输入和输出是一样的,那么我们便可以认为这样的Task是没有必要重复执行的。此时,反复执行相同的Task是冗余的,并且是耗时的。
为了解决这样的问题,Gradle引入了增量式构建的概念。在增量式构建中,我们为每个Task定义输入(inputs)和输入(outputs),如果在执行一个Task时,如果它的输入和输出与前一次执行时没有发生变化,那么Gradle便会认为该Task是最新的(UP-TO-DATE),因此Gradle将不予执行。一个Task的inputs和outputs可以是一个或多个文件,可以是文件夹,还可以是Project的某个Property,甚至可以是某个闭包所定义的条件。
每个Task都拥有inputs和outputs属性,他们的类型分别为TaskInputs和TaskOutputs。在下面的例子中,我们展示了这么一种场景:名为combineFileContent的Task从sourceDir目录中读取所有的文件,然后将每个文件的内容合并到destination.txt文件中。让我们先来看看没有定义Task输入和输出的情况:
task combineFileContentNonIncremental { def sources = fileTree('sourceDir') def destination = file('destination.txt') doLast { destination.withPrintWriter { writer -> sources.each {source -> writer.println source.text } } } }
多次执行“gradle combineFileContentNonIncremental”时,整个Task都会反复执行,即便在第一次执行后我们已经得到了所需的结果。如果该combineFileContentNonIncremental是一个繁重的Task,那么多次重复执行势必造成没必要的时间耗费。
这时,我们可以将sources声明为该Task的inputs,而将destination声明为outputs,重新创建一个Task如下:
task combineFileContentIncremental { def sources = fileTree('sourceDir') def destination = file('destination.txt') inputs.dir sources outputs.file destination doLast { destination.withPrintWriter { writer -> sources.each {source -> writer.println source.text } } } }
相比之下,后一个Task只比前一个Task多了两行代码:
inputs.dir sources
outputs.file destination
当首次执行combineFileContentIncremental时,Gradle会完整地执行该Task。但是紧接着再执行一次,命令行显示:
:combineFileContentIncremental UP-TO-DATE
BUILD SUCCESSFUL
Total time: 2.104 secs
我们发现,combineFileContentIncremental被标记为UP-TO-DATE,表示该Task是最新的,Gradle将不予执行。在实际应用中,你将遇到很多这样的情况,因为Gradle的很多插件都引入了增量式构建机制。
如果我们修改了inputs(即sourceDir文件夹)中的任何一个文件或删除掉了destination.txt,当调用“gradle combineFileContentIncremental”时,Gradle又会重新执行,因为此时的Task已经不再是最新的了。对于outputs,我们还可以使用upToDateWhen()方法来决定一个Task的outputs是否为最新的,该方法接受一个闭包作为检查条件,感兴趣的读者可以自行了解。
相关推荐
Gradle使用基于Groovy或Kotlin的声明式语言编写构建脚本,使得配置项目结构、依赖管理、构建任务等变得直观而灵活。在`gradle-2.8`中,你可以找到这些脚本,了解如何定义项目、添加依赖、定制构建过程。 依赖管理是...
增量构建是Gradle的核心特性之一,它允许只重新构建自上次构建以来发生变化的部分,而不是整个项目。在Gradle 4.9中,这一功能得到了进一步强化。通过智能跟踪文件变化和依赖关系,这个版本可以显著减少不必要的编译...
1. **基于DSL的构建脚本**:Gradle 使用Groovy或Kotlin作为构建脚本语言,提供了一种声明式的方式定义构建过程,使得构建配置更加简洁易懂。 2. **依赖管理**:Gradle 支持自动下载和管理项目依赖,可以从Maven仓库...
- **增量构建**:Gradle支持增量构建,仅重新处理自上次构建以来发生变化的部分,提高构建速度。 - **Android插件**:Android Gradle Plugin提供了一系列任务,如assembleDebug、assembleRelease,用于构建不同...
1. **增量构建**:Gradle能够跟踪文件变更,只重新构建必要的部分,提升构建速度。 2. **缓存优化**:合理配置本地和远程仓库,避免不必要的网络请求。 总结,Java Gradle产品演示展示了Gradle在构建Java项目中的...
`sbt`(Simple Build Tool)是Scala语言的构建工具,类似于Java的Maven或Gradle。这个修改版可能包含了对原始0.7.7版本的改进或修复,以适应开发者的需求或解决特定问题。 描述中提到的链接指向了Google Code的一个...
- **Maven或Gradle**:构建工具,管理项目依赖和构建流程。 3. **版本控制系统**: - **Git**:分布式版本控制系统,用于跟踪代码变更、协同开发。 - **GitHub或GitLab**:托管Git仓库的服务,提供代码仓库、...
4. **工具友好**:Kotlin的编译速度快,支持增量编译,且与构建工具如Gradle、Maven集成良好。此外,它的IDE支持(如IntelliJ IDEA和Android Studio)提供了强大的代码补全和智能提示。 5. **函数式编程**:Kotlin...