Gradle入门篇之自定义Task类

news/2024/11/29 3:41:27/

一、前言

    在编写Gradle脚本中,经常会使用到 Task,自定义Task的实现方法也有很多,最简单的就是在Gradle脚本中直接使用闭包的方式添加功能代码,这种类型的Task在实现一次性执行的操作非常方便,若这种方法无法满足要求时(或者为了实现更好的封装),就可以自定义 Task 类。自定义 Task 类的还有一个好处就是,可以将你定义的Task 类,封装成插件包,发布到仓库,在其他项目直接依赖使用。

二、自定义Task类的封装

    首先,我们先来了解下如何将自定义的Task类封装起来,这里总结起来有三种:

2.1 在构建脚本中(build script)

    你可以直接在构建脚本中声明Task类,这样做的一个好处就是,你无需做任何事情,Task类就会自动编译并添加到构建脚本的类路径中。然而,在构建脚本中定义的Task类,只能在当前构建脚本中可见,因此,无法在定义它的构建脚本之外复用。

2.2 在当前项目源码中(buildSrc project)

    你可以将 Task 类的源码放到项目的源代码目录中。Gradle 将会完成对Task类源码的编译测试,并让其在构建脚本的类路径中生效。Task 类将会在项目中的所有构建脚本中可用,但是对于项目意外的的项目构建,依旧不可用,因此你无法在外部项目构建中复用这些 Task 类(当然,你可以将这些 Task 类源码拷贝到其他项目,但是这就造成了代码的冗余等问题)。将 Task 类放到项目源码中,也实现了将任务声明(即任务应该做什么)与任务实现(即任务如何执行)分开。

特别说明:
将 Task 类放到项目源码中,根据语言的不同,目录有所不同。
1)基于groovy 语言,放到 rootProjectDir/buildSrc/src/main/groovy 目录;
2)基于 java 语言,放到 rootProjectDir/buildSrc/src/main/java 目录;
3)基于 kotlin 语言,放到 rootProjectDir/buildSrc/src/main/kotlin 目录。

2.3 在独立的项目中(standalone project)

    在上面的介绍中,既然 Task 类可以放到项目源码中,那么当然可以创建一个单独项目专门用于 Task 类源码的开发与管理,这个项目可以产出 并发布jar 文件,供其他项目使用。通常,这个jar库文件会包含一些自定义的插件,或打包一些关联的 Task 类,或两者都包含。你还可以将产出的 jar 文件发布到远程仓库中,其他项目可以直接通过远程仓库依赖引用,这个我们将在后面详细介绍。

三、自定义Task类

2.1 编写一个简单的 Task 类

    自定义Task类,你可通过继承 Gradle 中的 DefaultTask 类实现。如下示例:

abstract class CheckingTask extends org.gradle.api.DefaultTask {}

注意事项:自定义的 Task 类必须是可以继承的,也就是说自定义的 Task 类不能是 final 的。如果你使用 Kotlin 语言开发,要特别注意 kotlin 语法中,类定义默认是 final 的(Java 语法中,如果没有指定是 final,都不是 final),因此我们在定义 Task 类的时候,习惯性将 Task 类定义为 抽象类 (abstract),这样就可以确保 Task 类不是 final 的。

2.2 给 Task 类添加行为动作

    上面的示例中,Task 类没有做任何事情,可以通过在 Task 类中添加使用 TaskAction 注解标注的成员方法来添加行为动作。在 Task 执行过程中,Gradle 会自动识别这些成员方法并执行相关的行为动作。当然,除了添加成员方法之外,你还可以在构建Task对象的时候,通过 doFirstdoLast 闭包,向任务中添加行为动作,如下示例:

abstract class CheckingTask extends org.gradle.api.DefaultTask {@org.gradle.api.tasks.TaskActiondef checkDisk() {println "CheckingTask -- checking disk"}
}
tasks.register('doChecking', CheckingTask) {// 构建任务的时候,通过doFirst闭包添加行为动作doFirst {println "Start to check you computer"}doLast {println "Check computer finished"}
}
  • gradle doChecking -q 输出
Start to check you computer
CheckingTask -- checking disk
Check computer finished

2.3 给 Task 类添加属性

    我们可以向 Task 类中添加属性,这样就可以实现对 Task 的自定义。任务其实就是一个对象,我们可以通过对象设置它的属性和调用它的方法。如下示例:

abstract class CheckingTask extends org.gradle.api.DefaultTask {@org.gradle.api.tasks.Inputabstract org.gradle.api.provider.Property<String> getOwner() // 添加一个owner属性CheckingTask() {// 构造函数中设置默认值owner.convention("Unknown")}@org.gradle.api.tasks.TaskActiondef checkDisk() {println "CheckingTask -- checking disk -- ${owner.get()}"}
}
tasks.register('doChecking', CheckingTask) {owner = "Mr Zhang"doFirst {println "Start to check you computer"}doLast {println "Check computer finished"}
}
  • gradle doChecking -q 输出
Start to check you computer
CheckingTask -- checking disk -- Mr Zhang
Check computer finished

2.4 在独立项目中开发自定义 Task 类

    前面我们知道可以在一个独立的项目中开发 Task 类,打包和发布到仓库,这样就可以共享给其他项目使用,下面我们将详细讲解一下如何实现。

    首先,创建一个项目(示例是创建一个根项目的子项目),在项目级的 build.gradle 文件中添加插件声明和Gradle API依赖声明,如下示例所示:

plugins {id 'groovy' // Groovy 基于语言开发
}sourceSets {main {java.srcDirs = ["src/main/groovy"]}
}dependencies {// 引入Gradle Api 依赖implementation gradleApi()
}

    需要注意的是,项目 build.gradle 文件中引入的插件,需要根据使用的开发语言添加,上面示例是基于groovy语言,因此引入 groovy 插件id 'groovy'),如果使用 Java 语言,需要添加 java 插件(一般 JVM 项目已经默认引入,id 'java'),如果使用 Kotlin 语言,需要引如 kotlin jvm 插件(id 'org.jetbrains.kotlin.jvm')。如果源码不是放在 Gradle 默认的源码目录,还需要指定源码目录(使用 sourceSets 配置)。基于groovy 语言,默认 projectDir/src/main/groovy 目录;基于 java 语言,默认 projectDir/src/main/java 目录;基于 kotlin 语言,默认 projectDir/src/main/kotlin 目录。

注意事项:如果插件配置不正确或者源码目录不正确,将会导致源码不被编译,生成的目标 jar 将不会包含 Task 类。

    然后,将上面示例的代码移到独立项目中,放到 projectDir/src/main/groovy 目录下

  • src/main/groovy/com/example/CheckingTask.grooovy
import org.gradle.api.DefaultTask
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskActionabstract class CheckingTask extends DefaultTask {@Inputabstract Property<String> getOwner() // 添加一个owner属性GCheckingTask() {// 构造函数中设置默认值owner.convention("Unknown")}@TaskActiondef checkDisk() {println "CheckingTask -- checking disk -- ${owner.get()}"}
}

    接下来,我们需要做的就是将项目的编译目标 jar 发布到仓库,这样就可以在其他项目中使用依赖引用。发布远程仓库的方法可以参考帖子 使用Gradle发布工件到Maven仓库(新版)。本示例中为了演示,就采用发布到本地仓库的形式:

  • 在独立项目中的 build.gradle 添加 maven-publish 插件
plugins {id 'groovy'id 'maven-publish' // Gradle 发布仓库插件
}
  • 在独立项目中的 build.gradle 添加工件发布配置
publishing {publications {release(MavenPublication) {groupId "com.owen.test" // groupIdartifactId "ktcctask" // artifactIdversion "1.6" // 发布版本artifact "${project.buildDir}/libs/lib.jar" // 发布jar,执行发布任务时,确保发布的jar生成成功description "test task" // 说明描述}}
}

注意事项:发布工件,执行发布任务时请确保你发布的工件(jar)已经生成或者更新到最新,上面的示例中,需要每次都执行一次构建,才能完成编译更新。在下面,我们将介绍一个直接通过自定义任务的方式,执行一个任务就完成编译后发布的操作。

  • 自定义任务,完成编译后发布
tasks.register("publishReleaseToLocal") {dependsOn assemble // 依赖 assemble,在前置执行 assemble 任务,先生成最新的jar
}publishReleaseToLocal.configure {// 配置 publishReleaseToLocal 任务,以 maven-publish 创建的发布任务 publishReleasePublicationToMavenLocal 结束,// 表示最终要执行 publishReleasePublicationToMavenLocal 任务,将工件发布到仓库finalizedBy(publishReleasePublicationToMavenLocal) 
}
  • 执行 publishReleaseToLocal 任务
gradle publishReleaseToLocal -q

    完成以上的操作后,包含自定义 Task 类的工件就发布到了仓库(本地仓库在 用户目录/.m2 目录下可以找到工件内容),接下来,就是完成在其他项目中依赖引用自定义的 Task 类。在引用的项目的根项目级别的 build.gradle 文件中,添加插件依赖声明,如下示例:

buildscript {ext.kotlin_version = "1.4.0"repositories {google()mavenCentral()mavenLocal() // 本地仓库,如果是远程仓库私服,需配置私服}dependencies {classpath "com.android.tools.build:gradle:4.0.1"classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"// NOTE: Do not place your application dependencies here; they belong// in the individual module build.gradle filesclasspath "com.owen.test:ktcctask:1.6" // 配置自定义 Task 类仓库依赖}}

    完成仓库配置和依赖配置,就可以在项目中引用自定义的 Task 类。

tasks.register('doChecking', CheckingTask) {owner = "Mr Zhang"doFirst {println "Start to check you computer"}doLast {println "Check computer finished"}
}
  • gradle doChecking -q 执行任务,输出:
Start to check you computer
CheckingTask -- checking disk -- Mr Zhang
Check computer finished

四、写在最后

    其实自定义任务类还是比较简单,但是也需要注意一些细节,比如任务类必须是非 final 的(可继承)。学会基本的自定义任务类,为后续编写更加复杂的任务,甚至是编写插件打下基础。本编到此结束,希望能帮到各位读者。


http://www.ppmy.cn/news/164147.html

相关文章

字节跳动春招——特征提取

小明是一名算法工程师&#xff0c;同时也是一名铲屎官。某天&#xff0c;他突发奇想&#xff0c;想从猫咪的视频里挖掘一些猫咪的运动信息。为了提取运动信息&#xff0c;他需要从视频的每一帧提取“猫咪特征”。一个猫咪特征是一个两维的vector<x, y>。如果x_1x_2 and y…

华为擎云计算机,终于来了!华为台式机擎云W510现身官网:国产CPU加持

今天下午&#xff0c;有微博博主爆料称&#xff0c;此前传闻已久的华为台式机正式现身华为开发者官网。据悉&#xff0c;这台主机将被命名为擎云W510&#xff0c;由富士康代工&#xff0c;主要面向政企客户&#xff0c;预计将于今年年内上市。 华为这款台式主机的设计比较简洁&…

n5100和n5105哪个好

n5100采用10纳米制造工艺 四核心 “CPU主频1.1-2.8 GHz 三级缓存4MB 热设计功耗6W 选n5105 还是n5100这些点很重要http://www.adiannao.cn/dy n5105采用10纳米制造工艺 四核心4线程 “CPU主频2-2.9GHz 三级缓存4MB 热设计功耗10W内存类型 DDR4 2933MHz&#xff0c;LPDDR4x 293…

华为擎云计算机,华为擎云台式机曝光:CPU+GPU全自研

原标题&#xff1a;华为擎云台式机曝光&#xff1a;CPUGPU全自研 目前国产电脑的呼声越来越高&#xff0c;此前已经有国产的天玥系列电脑问世&#xff0c;不过详细数据并没有爆料。而龙芯的产品目前也没有见到动静&#xff0c;这个时候外界对于华为台式机的关注度就无比高涨。 …

RT5350资料

openwrt 官网安装包 GDB

W5500的最新驱动库

官方提供了W5500的最新驱动库&#xff0c;下载地址如下&#xff1a; http://wizwiki.net/wiki/doku.php?idproducts:w5500:driver

不怕死就上这些网站

1. hxxp:///www.dj3344.com 打开后&#xff0c;重启时你的主页就变成它的&#xff0c;并通过QQ向他人传播&#xff0c;现在正飙行&#xff0c;奇坏无比&#xff01;2. hxxp:///www.qq168.net 打开后&#xff0c;重启时你的主页就变成它的&#xff0c;并通过QQ向他人传播&#x…

W5100常见问题汇总

1.[问题]W5100的功耗是多少&#xff1f; 正常运行&#xff1a;低于150mA 初始运行&#xff1a;190mA 我们建议设计应该是基于200mA的情况来处理。 2.[问题]W5100兼容5V电压吗&#xff1f; W5100基于3.3V电压工作&#xff0c;I/O接口容忍5V电压。因此&#xff0c;如果你使用…