添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

1.1 incremental task 与 incremental task action

incremental task(增量 task): 当输入改变时,可以只处理改变的部分。一个 incremental task 需要实现一个 incremental task action

incremental task action(增量 task action): 一个被 @TaskAction 注解的方法,它接收一个 IncrementalTaskInputs 参数。可以在 IncrementalTaskInputs 的 outOfDate 方法里处理改变的 input,在 removed 方法里处理移除的 input。

1.2 判断标准

可以通过 IncrementalTaskInputs.incremental 来判断,Gradle 是否可以判断哪些 input 发生了改变。

Gradle 可以判断哪些 input 发生了变化:

  • 当 task 的执行环境与上次执行时相比,只有 input 发生了改变,那改变的 input 就会被认为 out-of-date。
  • 这时,只有改变的 input 会执行 outOfDate action。

    Gradle 无法判断哪些 input 发生了改变:

  • 没有前一次执行的记录
  • 使用不同版本的 Gradle 执行
  • upToDateWhen 返回了 false
  • 一个 input 属性发生了变化
  • 一个或多个 output 发生了变化
  • 这时,所有的 input 都会执行 outOfDate action。

    二、执行实例

    2.1 IncrementalReverseTask 类

    class IncrementalReverseTask extends DefaultTask {
        @InputDirectory
        // @InputDirectory 指定一个 property 作为 task 的输入目录
        // 目录的 path 或 content 改变后,task 会被认为 out-of-date
        File inputDir
        @OutputDirectory
        // @OutputDirectory 指定一个 property 作为 task 的输出目录
        // 目录的 path 或 content 改变后,task 会被认为 out-of-date
        File outputDir
        @Input
        // @Input 注解指定一个 property 作为 task 的输入值,它的值改变后,task 将会认为 out-of-date
        // 当使用 File 作为 Input 时,File 的 path 改变才认为 out-of-date;File 的 content 改变不会认为 out-of-date
        def inputProperty
        @TaskAction
        // @TaskAction 注解表示 task 要执行的动作
        void execute(IncrementalTaskInputs inputs) {
            // inputs.incremental: Gradle 是否能判断 input 的改变
            // 如一个或多个 output file 发生改变,Gradle 无法判断哪个 input 发生了改变,inputs.incremental 会返回 false
            // 所以的 input 都会认为 out-of-date
            println inputs.iscremental ? 'CHANGED inputs considered out of date'
                    : 'ALL inputs considered out of date'
            if (!inputs.incremental)
                project.delete(outputDir.listFiles())
            // 发生改变的 input 要执行的 action
            inputs.outOfDate { change ->
                if (change.file.directory) return
                println "out of date: ${change.file.name}"
                def targetFile = new File(outputDir, change.file.name)
                targetFile.text = change.file.text.reverse()
            // 被移除的 input 要执行的 action
            inputs.removed { change ->
                if (change.file.directory) return
                println "removed: ${change.file.name}"
                def targetFile = new File(outputDir, change.file.name)
                targetFile.delete()
    复制代码

    2.2 IncrementalReverseTask 类型的 task

    task incrementalReverse(type: IncrementalReverseTask) {
        inputDir = file('inputs')
        outputDir = file("$buildDir/outputs")
        inputProperty = project.properties['taskInputProperty'] ?: 'original'
    复制代码

    2.3 第一次执行

    // 初始化 inputs 目录
    task originalInputs() {
        doLast {
            file('inputs').mkdir()
            file('inputs/1.txt').text = 'Content for file 1.'
            file('inputs/2.txt').text = 'Content for file 2.'
            file('inputs/3.txt').text = 'Content for file 3.'
    复制代码

    执行

    $ ./gradlew -q originalInputs incrementalReverse 
    ALL inputs considered out of date
    out of date: 3.txt
    out of date: 2.txt
    out of date: 1.txt
    复制代码

    2.4 无改变第二次执行

    $ ./gradlew -q incrementalReverse
    复制代码

    无输出

    2.5 更新 input 后执行

    task updateInputs() {
        doLast {
            file('inputs/1.txt').text = 'Changed content for existing file 1.'
            file('inputs/4.txt').text = 'Content for new file 4.'
    复制代码

    执行

    $ ./gradlew -q updateInputs incrementalReverse
    CHANGED inputs considered out of date
    out of date: 1.txt
    out of date: 4.txt
    复制代码

    2.6 移除 input 后执行

    task removeInput() {
        doLast {
            file('inputs/3.txt').delete()
    复制代码

    执行

    $ ./gradlew -q removeInput incrementalReverse
    CHANGED inputs considered out of date
    removed: 3.txt
    复制代码

    2.7 移除 output 后执行

    task removeOutput() {
        doLast {
            file("$buildDir/outputs/1.txt").delete()
    复制代码

    执行

    $ ./gradlew -q removeOutput incrementalReverse
    ALL inputs considered out of date
    out of date: 4.txt
    out of date: 2.txt
    out of date: 1.txt
    复制代码

    2.8 改变 input 属性后执行

    $ ./gradlew -q -PtaskInputProperty=changed incrementalReverse
    ALL inputs considered out of date
    out of date: 4.txt
    out of date: 2.txt
    out of date: 1.txt
    复制代码
    分类:
    Android
    标签: