美文网首页
Gradle第7课:Gradle 中自定义任务的实现

Gradle第7课:Gradle 中自定义任务的实现

作者: 米饭超人 | 来源:发表于2018-08-28 11:08 被阅读157次

需要准备

  • 一个熟悉的 IDE 开发工具
  • JDK 7及以上
  • Gradle 3.2以上

Gradle 的两种任务类型

在上一章中, 我们介绍了任务( Task )的一些高级用法,知道了 Gradle 对任务的功能增强很多,那么它是具体如何做到的呢?在揭晓答案之前,我们先来看看 Gradle 都支持哪两种类型的任务吧。

第一种为简单任务类型,就是我们在第四节中介绍的, 它的行为是定义在一个动作闭包方法中的,这种简单类型的任务适合在一个编译脚本中实现一种功能。

而第二种为增强的任务类型,它的行为被提前构建在了任务里,只是提供一些配置属性让我们去设置,这种任务可以在不的地方或不同的编译脚本中被重复使用,它正是我们在上一节中介绍过的任务类型。

这种高级的增强的任务类型是通过定义一个任务类来实现的,在 Gradle 中我们也可以自定义自己的增强类型类,我们可以使用多种语言来实现,比如 java、scala 等。不过 Gradle 本身是使用 Groovy 语言实现的,所以我在这里选择使用 Groovy 语言来实现。

实现自定义的任务类型

首先有三种方式来编写我们的任务类

  1. 在我们构建项目的 build.gradle 脚本中直接编写,这种方式的好处是任务类自动被编译加载到我们的 classpath 中,我们不需要额外做任何的事情,但是它有很明显的局限性,就是除了在包括它的脚本外别的地方无法复用。

  2. 在我们构建项目的rootProjectDir/buildSrc/src/main/groovy 目录下编写,Gradle 会自动编译到当前项目的 classpath 中,该项目下所有编译脚本都可以使用,但是除了当前项目之外的都无法复用。

  3. 以单独的工程方式编写,这个工程最终编译发布为一个 JAR 包,它可以在多个项目或不同的团队中共享使用。

然后我们先使用第一种方式编写一个简单的自定义任务类,而该自定义任务类是继承自DefaultTask的,同时为它添加一个行为方法,该方法需要使用TaskAction进行标注,这样 Gradle 就会在任务执行的时候默认调用它,其 build.gradle 中代码如下所示:

task hello(type: GreetingTask)

class GreetingTask extends DefaultTask {
    @TaskAction
    def greet() {
        println 'hello from GreetingTask'
    }
}

执行命令gradle -q hello结果如下:

> gradle -q hello
hello from GreetingTask

当然我们可以为我们自定义的任务类添加属性,并且在使用的时候设置该属性值,其 build.gradle 中代码如下:

// 使用默认的属性值
task hello(type: GreetingTask)

// 自定义设置的属性值
task greeting(type: GreetingTask) {
    greeting = 'greetings from GreetingTask'
}

class GreetingTask extends DefaultTask {
    String greeting = 'hello from GreetingTask'

    @TaskAction
    def greet() {
        println greeting
    }
}

执行命令gradle -q hello greeting结果如下:

> gradle -q hello greeting
hello from GreetingTask
greetings from GreetingTask

以单独工程方式实现自定义任务类

我们使用 IDEA 开发工具创建一个 Groovy 的工程,然后在它的build.gradle文件中使用 Groovy plugin,并且添加相关的依赖,代码如下:

apply plugin: 'groovy'

dependencies {
    compile gradleApi()
    compile localGroovy()
}

接着创建一个 Groovy类 ,其文件为src/main/groovy/org/gradle/GreetingTask.groovy,相关代码如下:

package org.gradle

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

class GreetingTask extends DefaultTask {
    String greeting = 'hello from GreetingTask'

    @TaskAction
    def greet() {
        println greeting
    }
}

我们可以使用 maven-publish 插件先发布到本地,这样我们机器上的其他工程就能在指定目录下找到我们的任务类了,修改 build.gradle 中代码如下:

apply plugin: 'groovy'
apply plugin: 'maven-publish'

dependencies {
    compile gradleApi()
    compile localGroovy()
}

publishing{
    publications {
        mavenJava(MavenPublication) {
            from components.java

            groupId 'org.gradle'
            artifactId 'customPlugin'
            version '1.0-SNAPSHOT'

        }
    }

    repositories{
        maven {
            // change to point to your repo, e.g. http://my.org/repo
            url "../repo"
        }
    }
}

在 IDEA 工具中直接运行 publish 任务,就能完成发布工作,并在工程的上一级目录下生成发布包,具体操作和结果如下图所示:

enter image description here enter image description here

最后在另外一个工程中使用该任务类

使用 IDEA 开发工具新创建一个 Gradle 工程,在该工程中将使用我们上面单独定义的任务类,首先我们需要使用 buildscript { } 块来使类添加到编译脚本的 classpath 中,下面 build.gradle 中的代码展示了如果加载本地仓库的任务类:

buildscript {
    repositories {
        maven {
            url uri('../repo')
        }
    }
    dependencies {
        classpath group: 'org.gradle', name: 'customPlugin',
                  version: '1.0-SNAPSHOT'
    }
}

task greeting(type: org.gradle.GreetingTask) {
    greeting = 'another project working!'
}

执行命令gradle -q greeting的结果如下:

> gradle -q greeting
another project working!

小结

本章通过实现了一个自定义任务类,让我们了解到了 Gradle 是如何增强任务功能的,下一节中将继续介绍如何实现自定义的插件,自定义任务类一般是与自定义插件一起使用的。

相关文章

网友评论

      本文标题:Gradle第7课:Gradle 中自定义任务的实现

      本文链接:https://www.haomeiwen.com/subject/pnlfwftx.html