Gradle教程系列 —— Project 和 Task

Gradle中的所有内容都基于两个基本概念:项目(Project)和任务(Task)。每个Gradle构建都是由一个或多个project组成。每个project都是有一个或者多个任务组成。任务之间具有依赖关系,保证了任务的执行顺序。任务代表构建执行的一些原子工作。这可能是编译某些类,创建JAR,生成Javadoc或将一些jar或者aar文件发布到maven仓库。

Project

我们首先讲一下Project的概念。每个build.gradle 就对应一个project。构建中的每一个project,Gradle都会创建一个Project对象,并将这个对象与构建脚本相关联。简单的说,build.gradle是对一个Project对象的配置。以Android项目为例,在项目的根目录会有一个build.gradle文件,在每个模块的目录下也会有一个build.gradle 文件。

Project与build.gradle是一对一的关系。在构建初始化阶段,Gradle为每个参与构建的项目创建一个Project对象。

  • 我们在构建脚本中调用的没有在构建脚本中定义的方法都委派给Project对象。

举例,project.copy() 等价于 copy()

  • 我们在在构建脚本中调用的没有在构建脚本中定义的属性都委派给Project对象。

举例,project.buildDir 等价于 buildDir

Task

任务是主要的工作执行者。每个任务有多个Action组成。

任务的定义

我们可以用以下方式创建task

方式一

task hello {
    doLast {
         println 'Hello Gradle!'
    }
}

运行这个task,gradle hello

> gradle -q hello
Hello Gradle!

方式二

tasks.create('hello2') {
    doLast {
        println "Hello Gradle!"
    }
}

方式三

task('hello3') {
    doLast {
        println "Hello Gradle!"
    }
}

方式四

@TaskAction 注解表示当任务执行时,被该@TaskAction 注解的方法就是该任务的入口。

class CustomTask extends DefaultTask {
    @TaskAction
    def hello() {
        doLast {
            println "Hello Gradle!"
        }
     }
}

任务的依赖

在使用任务时,可以使用dependsOn关键词声明任务与任务的依赖关系。任务依赖的主要意义在于,确定任务与任务之间的执行先后顺序。任务与任务之间构成一个有向无环图(DAG),每个任务最多执行一次。

举例,任务intro依赖于任务hello,那么在执行intro之前,必定先执行hello任务。

task hello {
    doLast {
        println 'Hello world!'
    }
}
task intro(dependsOn: hello) {
    doLast {
        println "I'm Gradle"
    }
}

运行结果

> gradle -q intro
Hello world!
I'm Gradle

添加任务的说明

我们还可以使用description添加任务说明。执行gradle任务时会显示此说明。

task hello {
    description 'This is the Hello Task'
    doLast {
        println "Hello Gradle!"
    }
}

Configure by DAG

在Gradle构建生命周期中,Gradle有配置阶段和执行阶段。在配置阶段,Gradle明确了需要执行的所有任务。Gradle为我们提供了一个利用这些信息的钩子(hook)。举例来讲,我们可以为不同的任务,分配不同的变量值或者执行不同的代码逻辑。

task distribution {
    doLast {
        println "We build the zip with version=$version"
    }
}

task release(dependsOn: 'distribution') {
    doLast {
        println 'We release now'
    }
}

gradle.taskGraph.whenReady {taskGraph ->
    if (taskGraph.hasTask(release)) {
        version = '1.0'
    } else {
        version = '1.0-SNAPSHOT'
    }
}

输出结果

> gradle -q distribution
We build the zip with version=1.0-SNAPSHOT

> gradle -q release
We build the zip with version=1.0
We release now

构建脚本的外部依赖项

import org.apache.commons.codec.binary.Base64

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
    }
}

task encode {
    doLast {
        def byte[] encodedString = new Base64().encode('hello world\n'.getBytes())
        println new String(encodedString)
    }
}

输出结果

> gradle -q encode
aGVsbG8gd29ybGQK

任务的执行结果

任务结果含义
EXECUTEDtask的action已经执行
UP-TO-DATEtask的输出没有改变,参考增量构建
FROM-CACHE可以从之前的输出中得到任务的输出
SKIPPEDtask没有执行它的action
NO-SOURCEtask不需要执行它的action

总结

Gradle基本是由project和task组成。因此,理解了Project和Task的含义和用法,也就更容易理解Gradle是如何运行以及如何使用的。

    原文作者:nxiangbo
    原文地址: https://www.jianshu.com/p/dd0fe9329c8c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞