Gradle学习系列之九——自定义Task类型
在本系列的上篇文章中,我们学习了多Project构建,在本篇文章中,我们将学到如何自定义Task类型。
请通过以下方式下载本系列文章的Github示例代码:
git clone https://github.com/davenkin/gradle-learning.git
在前面的文章中我们讲到,Gradle本身只是一个架子,真正起作用的是Task和Plugin。要真正了解Task和Plugin的工作机制并熟练运用,学会自定义Task类型和Plugin是大有裨益的。
Gradle中的Task要么是由不同的Plugin引入的,要么是我们自己在build.gradle文件中直接创建的。在默认情况下,我们所创建的Task是DefaultTask类型,该类型是一个非常通用的Task类型,而在有些时候,我们希望创建一些具有特定功能的Task,比如Copy和Jar等。还有时候,我们希望定义自己创建的Task类型,在本文中,我们以定义一个简单的HelloWorldTask为例,讲解如何自定义一个Task类型,并且如何对其进行配置。
在Gradle中,我们有3种方法可以自定义Task类型。
(一)在build.gradle文件中直接定义
我们知道,Gradle其实就是groovy代码,所以在build.gradle文件中,我们便可以定义Task类。
class HelloWorldTask extends DefaultTask {
@Optional
String message = 'I am davenkin' @TaskAction
def hello(){
println "hello world $message"
}
} task hello(type:HelloWorldTask) task hello1(type:HelloWorldTask){
message ="I am a programmer"
}
在上例中,我们定义了一个名为HelloWorldTask的Task,它需要继承自DefaultTask,它的作用是向命令行输出一个字符串。@TaskAction表示该Task要执行的动作,即在调用该Task时,hello()方法将被执行。另外,message被标记为@Optional,表示在配置该Task时,message是可选的。在定义好HelloWorldTask后,我们创建了两个Task实例,第一个hello使用了默认的message值,而第二个hello1在创建时重新设置了message的值。
在执行hello时,命令行输出如下:
:hello
hello world I am davenkin BUILD SUCCESSFUL Total time: 2.139 secs
在执行hello1时,命令行输出如下:
:hello1
hello world I am a programmer BUILD SUCCESSFUL
(二)在当前工程中定义Task类型
在(一)中,我们在build.gradle中直接定义了Task的类型,这样将Task的定义和使用混在一起。在需要定义的Task类型不多时,我们可以采用这种方法,但是在项目中存在大量的自定义Task类型时,这就不见得是中好的做法了。一种改进方法是在另外的一个gradle文件中定义这些Task,然后再apply到build.gradle文件中。这里,我们将使用另一种方法:在buildSrc目录下定义Task类型,Gradle在执行时,会自动地查找该目录下所定义的Task类型,并首先编译该目录下的groovy代码以供build.gradle文件使用。
在当前工程的buildSrc/src/main/groovy/davenkin目录下创建HelloWorldTask.groovy文件,将(1)中对HelloWorldTask的定义转移到该文件中:
package davenkin
import org.gradle.api.*
import org.gradle.api.tasks.* class HelloWorldTask extends DefaultTask {
@Optional
String message = 'I am davenkin' @TaskAction
def hello(){
println "hello world $message"
}
}
这里,我们将HelloWorldTask定义在了davenkin包下,因此在build.gradle文件中引用该Task时,我们需要它的全名称:
task hello(type:davenkin.HelloWorldTask) task hello1(type:davenkin.HelloWorldTask){
message ="I am a programmer"
}
以上的hello和hello1与(1)中的hello和hello1完成的功能相同。
(三)在单独的项目中定义Task类型
虽然(2)中的Task定义与build.gradle分离开了,但是它依然只能应用在当前工程中。如果我们希望所定义的Task能够用在另外的项目中,那么(2)中的方法便不可行的,此时我们可以将Task的定义放在单独的工程中,然后在所有使用Task的工程中通过声明依赖的方式引入这些Task。
创建另外一个项目,将(2)中buildSrc目录下的内容考到新建项目中,由于该项目定义Task的文件是用groovy写的,因此我们需要在该项目的build.gradle文件中引入groovy Plugin。另外,由于该项目的输出需要被其他项目所使用,因此我们还需要将其上传到repository中,在本例中,我们将该项目生成的包含了Task定义的jar文件上传到了本地的文件系统中。最终的build.gradle文件如下:
apply plugin: 'groovy'
apply plugin: 'maven'
version = '1.0'
group = 'davenkin'
archivesBaseName = 'hellotask' repositories.mavenCentral() dependencies {
compile gradleApi()
groovy localGroovy()
}
uploadArchives {
repositories.mavenDeployer {
repository(url: 'file:../lib')
}
}
执行“gradle uploadArchives”,所生成的jar文件将被上传到上级目录的lib(../lib)文件夹中。
在使用该HelloWorldTask时,客户端的build.gradle文件可以做以下配置:
buildscript {
repositories {
maven {
url 'file:../lib'
} } dependencies {
classpath group: 'davenkin', name: 'hellotask', version: '1.0'
}
} task hello(type: davenkin.HelloWorldTask)
首先,我们需要告诉Gradle到何处去取得依赖,即配置repository。另外,我们需要声明对HelloWorldTask的依赖,该依赖用于当前build文件。之后,对hello的创建与(2)中一样。
在下一篇文章中,我们将讲到如何自定义Plugin。
Gradle学习系列之九——自定义Task类型的更多相关文章
- Gradle学习系列之十——自定义Plugin(本系列完)
在本系列的上篇文章中,我们讲到了如何自定义Task类型,在本篇文章中,我们将讲到如何自定义Plugin. 请通过以下方式下载本系列文章的Github示例代码: git clone https://gi ...
- Gradle学习系列之二——创建Task的多种方法
在本系列的上篇文章中,我们讲到了Gradle入门,在本篇文章中我们将讲到创建Task的多种方法. 请通过以下方式下载本系列文章的Github示例代码: git clone https://github ...
- Gradle学习系列之一——Gradle快速入门
这是一个关于Gradle的学习系列,其中包含以下文章: Gradle快速入门 创建Task的多种方法 读懂Gradle语法 增量式构建 自定义Property 使用java Plugin 依赖管理 构 ...
- Gradle学习系列之一——Gradle快速入门(转)
这是一个关于Gradle的学习系列,其中包含以下文章: Gradle快速入门 创建Task的多种方法 读懂Gradle语法 增量式构建 自定义Property 使用java Plugin 依赖管理 构 ...
- Gradle学习系列之八——构建多个Project
在本系列的上篇文章中,我们讲到了Gradle的依赖管理,在本篇文章中,我们将讲到如何构建多个Project. 请通过以下方式下载本系列文章的Github示例代码: git clone https:// ...
- Python学习系列(九)(IO与异常处理)
Python学习系列(九)(IO与异常处理) Python学习系列(八)( 面向对象基础) 一,存储器 1,Python提供一个标准的模块,称为pickle,使用它既可以在一个文件中存储任何Pytho ...
- Gradle学习系列之四——增量式构建
在本系列的上篇文章中,我们讲到了如何读懂Gradle的语法,在本篇文章中,我们将讲到增量式地构建项目. 请通过以下方式下载本系列文章的Github示例代码: git clone https://git ...
- Dubbo学习系列之九(Shiro+JWT权限管理)
村长让小王给村里各系统来一套SSO方案做整合,隔壁的陈家村流行使用Session+认证中心方法,但小王想尝试点新鲜的,于是想到了JWT方案,那JWT是啥呢?JavaWebToken简称JWT,就是一个 ...
- [C#] 类型学习笔记三:自定义值类型
既前两篇之后,这一篇我们讨论通过struct 关键字自定义值类型. 在第一篇已经讨论过值类型的优势,节省空间,不会触发Gargage Collection等等. 在对性能要求比较高的场景下,通过str ...
随机推荐
- 使用 SELinux 和 Smack 增强轻量级容器
http://www.bitscn.com/os/linux/200904/158771.html 安全 Linux 容器实现指南 轻量级容器 又称作 Virtual Private Servers ...
- S7-200系列PLC与WINCC以太网通信CP243i的实例
S7-200系列PLC与WINCC以太网通信CP243i的实例 ----选用大连德嘉国际电子www.dl-winbest.cn的CP243i作为连接S7-200的PPI口转以太网RJ45的接口转换器. ...
- 纯CSS实现图片抖动
实现方法: 1.将上文提到的以下JS内容删除: $(".imagelogo").mouseover(function() { obj = $(this); i = 5; timer ...
- AndroidStudio小技巧--依赖库
同步发表于http://avenwu.net/2015/02/12/androidstudio_library_dependency Fork on github https://github.com ...
- Openvswitch原理与代码分析(4):网络包的处理过程
在上一节提到,Openvswitch的内核模块openvswitch.ko会在网卡上注册一个函数netdev_frame_hook,每当有网络包到达网卡的时候,这个函数就会被调用. stati ...
- C# 向Http服务器送出 POST 请求
//向Http服务器送出 POST 请求 public string m_PostSubmit(string strUrl,string strParam) { string strResult = ...
- 管理批量邮箱 FOXMAIL 和网易闪电邮(PC端)有什么区别? 对比
喜欢用FOXMAIL有订阅功能<img src="https://pic1.zhimg.com/fa72df2440f84043a5275b90df30b2f4_b.jpg&q ...
- Spark源码系列(一)spark-submit提交作业过程
前言 折腾了很久,终于开始学习Spark的源码了,第一篇我打算讲一下Spark作业的提交过程. 这个是Spark的App运行图,它通过一个Driver来和集群通信,集群负责作业的分配.今天我要讲的是如 ...
- memcpy 和直接赋值的性能差异
不废话,看代码: #include <time.h> #include <stdint.h> #include <iostream> #define ARR_LEN ...
- MySQL实现类似Oracle的序列
MySQL实现类似Oracle的序列 2013-10-22 10:33:35 我来说两句 作者:走过的足迹 收藏 我要投稿 MySQL实现类似Oracle的序列 Oracl ...