博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android Gradle 自定义Task 详解
阅读量:6951 次
发布时间:2019-06-27

本文共 6758 字,大约阅读时间需要 22 分钟。

转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/76408024

本文出自

一:Gradle 是什么

  • Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具。
  • 它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。面向Java应用为主。
  • 当前其支持的语言限于Java、Groovy、Kotlin和Scala,计划未来将支持更多的语言。基于 groovy 脚本构建,其 build 脚本使用 groovy 语言编写。

关于 gradle 相关运用,可以移步 :

二:groovy 是什么

Groovy是一种动态语言,它和Java类似(算是Java的升级版,但是又具备脚本语言的特点),都在Java虚拟机中运行。当运行Groovy脚本时它会先被编译成Java类字节码,然后通过JVM虚拟机执行这个Java字节码类。

关于 groovy 相关知识,移步到这里:

三:Gradle 的 Project 和 Tasks

每次构建(build)至少由一个project构成,一个project 由一到多个task构成。每个task代表了构建过程当中的一个原子性操作,比如编译,打包,生成javadoc,发布等等这些操作。

gradle : 一个 project 包含多个 task,一个 task 包含多个 Action

project                   -- task1 (Action1、Action2...)                  -- task2 (Action1、Action2...)                  -- ...

四:自定义 Task

  • 格式:
task 任务的名字 {    //do some things }
  • 例子

build.gradle

//定义 task , 名字 hello task hello{    println "hello world"}//定义 task,名字 hello task(hello2){    println "hello world2"}//定义 task,名字 hello3 task ('hello3'){    println "hello world3"}
  • 在终端运行 gradle 命令
//执行 hello taskgradlew hello//执行 hello2 taskgradlew hello2//执行 hello3 taskgradlew hello3

五:创建Action

在上面的举例中,是一个非正式的 task , 说非正式是因为创建的 task 里面没有 action 。task 本质上又是由一组被顺序执行的 Action 对象构成,Action其实是一段代码块,类似于Java中的方法。

创建 Action 相关 API

//在Action 队列头部添加Action Task doFirst(Action
action); Task doFirst(Closure action); //在Action 队列尾部添加Action Task doLast(Action
action); Task doLast(Closure action); //已经过时了,建议用 doLast 代替 Task leftShift(Closure action); //删除所有的Action Task deleteAllActions();

小例子

build.gradle

//创建一个名字为hello的 task task hello {    //创建一个 Action , 添加到 Action 列表的头部   doFirst(new Action
() { @Override void execute(Task task) { println "action1++++++++++" } }) //创建一个 Action , 添加到 Action 列表的头部 doFirst { println "action2++++++++++" }}

在 Action 列表中添加了 两个 Action , Action 列表如下图所示:

这里写图片描述

运行 hello task : gradle hello

运行结果:

action2++++++++++action1++++++++++

leftShift 说明

leftShift 的作用和 doLast 一样,在action 列表尾部添加一个Action,只不过现在过时了,官方建议用 doLast 代替。下面举个小例子:

build.gradle

task hello {    //在 Action 列表尾部添加一个 Action     leftShift {        println "+++++"    }}

leftShift 还有一种简洁写法,用 << 代替, 如下所示:

build.gradle

task hello <<{    //在 Action 列表尾部添加一个 Action     println "+++++"}

那么问题来了,task 中的 Action 在什么时候执行?

六:Gradle 生命周期

1.初始化阶段

会去读取根工程中 setting.gradle 中的 include 信息,决定有哪几个工程加入构建,创建 project 实例,比如下面有三个工程: include ':app', ':lib1', ':lib2 。

2.配置阶段

会去执行所有工程的 build.gradle 脚本,配置 project对象,一个对象由多个任务组成,

此阶段也会去创建、配置task及相关信息。

3.运行阶段

根据gradle命令传递过来的task名称,执行相关依赖任务。Task 的 Action 会在这个阶段执行。

七:创建 Task 的另外一种方式

在上面讲解了创建 task 的基本方式,其实 gradle api 给我们提供了其他的方式创建 task ,下面讲解其他两种方式。

  • tasks

build.gradle

//创建 hello2 tasktasks.create("hello2"){    doFirst {        println "hello2+++++"    }}
  • 自定义 DefaultTask 子类
class MyTask extends DefaultTask {        @TaskAction    void action(){        println "action1+++++"    }}//创建 hello3 tasktask hello3 (type: MyTask){    doLast{       println "action2+++++"    }}

运行 hello3 task: gradlew hello3

输出

action1+++++

action2+++++

八: Task 依赖

1、dependsOn

build.gradle

task task1 << {    println "我是task1----"}task task2 << {    println "我是task2----"}//task2 依赖 task1, 执行task2之前先执行task1task2.dependsOn task1

执行 task2

gradlew task2

执行效果

我是task1----

我是task2----

2、mustRunAfter

两个 task 依赖

task task1 << {    println "我是task1----"}task task2 << {    println "我是task2----"}//task2 运行之前先运行task1task2.mustRunAfter task1
  • 执行 task1 : gradlew task1

    我是task1----

  • 执行 task2 : gradlew task2

    我是task2----

  • 同时执行 task1、task2 : gradlew task1 task2

    我是task1----

    我是task2----

三个 task 相互依赖

build.gradle

task task1 << {    println "我是task1----"}task task2 << {    println "我是task2----"}task task3 << {    println "我是task3----"}task2.mustRunAfter task1task3.mustRunAfter task1
  • 执行 gradlew task1 task2 task3

    我是task1----

    我是task2----
    我是task3----

  • 执行 gradlew task1 task3 task2

    我是task1----

    我是task3----
    我是task1----

在出现语法矛盾的情况下,依赖关系形成闭环,编译器会报错

task1.mustRunAfter task2task2.mustRunAfter task1

markdown_test_TIM%E6%88%AA%E5%9B%BE20171102171717.png

3、shouldRunAfter

形成依赖关系可有可无。

build.gradle

task task1 << {    println "我是task1----"}task task2 << {    println "我是task2----"}task1.shouldRunAfter task2

运行: gradlew task1 task2

我是task2----

我是task1----

在出现语法矛盾的情况下,依赖关系形成闭环,会自动打破闭环。不会报错

九:系统默认 task

gradle 默认提供了很多 task 给我们使用,比如 copy、delete

1、copy

build.gradle

task 任务的名字 (type: Copy) {    //action }
  • Api 介绍
//数据源目录,多个目录public AbstractCopyTask from(Object... sourcePaths)  //目标目录,单一public AbstractCopyTask into(Object destDir) //过滤文件 包含public AbstractCopyTask include(String... includes)//过滤文件 排除public AbstractCopyTask exclude(String... excludes)//重新命名,老名字 新名字public AbstractCopyTask rename(String sourceRegEx, String replaceWith)//删除文件 Project 接口boolean delete(Object... paths);

小例子:

  • 复制图片:单一数据源
task copyImage(type: Copy) {    from 'C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy'    into 'C:\\Users\\yiba_zyj\\Desktop'}
  • 复制图片:多个数据源
task copyImage(type: Copy) {    from 'C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy' ,          'C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy'        into 'C:\\Users\\yiba_zyj\\Desktop'}
  • 复制图片:过滤文件

只会复制后缀为 .jpg 的文件

task copyImage(type: Copy) {    from 'C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy'    into 'C:\\Users\\yiba_zyj\\Desktop'    include "*.jpg" }
  • 复制文件:过滤文件,重命名
task copyImage(type: Copy) {    from 'C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy'    into 'C:\\Users\\yiba_zyj\\Desktop'    include "*.jpg"    exclude "image1.jpg"    rename("image2.jpg","123.jpg")}

文件覆盖规则

相同文件覆盖

Copy 类的继承图

Copy (类)   - AbstractCopyTask (抽象类)  (from、 into、 include、rename)      -ConventionTask(抽象类)       - DefaultTask (类)        - AbstractTask (抽象类)           - TaskInternal (接口)            - Task(接口)                      -Comparable
, ExtensionAware(接口) -Project(接口) (delete 方法)

2、Delete

  • 删除 Android 更目录的aaa 文件

build.gradle

task deleteFile(type: Delete) {    //删除Android 更目录的aaa 文件    delete '../aaa'  }
  • 删除桌面上的文件

build.gradle

task deleteFile(type: Delete) {    //删除系统桌面 delete     delete "C:\\Users\\yiba_zyj\\Desktop\\gradle\\delete"}

十:小技巧

1、自定义 task 的名字用驼峰命名法

build.gradle

task deleteFile{    //do some things}

运行

gradlew dF 等价 gradlew deleteFile

打包时候运行 gradlew assembleRelease,可以简写成 gradlew aR

2、常见的 gradlew 命令

查看项目所有默认自带的 task,不包括自定义 task

gradlew tasks

查看所有 task (默认 task + 自定义task)

gradlew tasks --all

查看某个 task 的相关信息,这些结果包含了任务的路径、类型以及描述信息等

gradlew help --task taskName

查看 gradle 版本

gradlew -version

3、给task 添加描述 description

task task1 << {    description = "这是一段描述信息"    println "我是task1----"}

十一:Gradle 环境变量配置

在上面的介绍中,运行 task 的方式是用 gradlew , 那我们怎么用 gradle 。如果在终端运行 gradle 就会提示 gradle 不是内部或外部命令,也不是可运行的程序或批处理文件。

'gradle' 不是内部或外部命令,也不是可运行的程序或批处理文件。

官网下载:

markdown_test_TIM%E6%88%AA%E5%9B%BE20171102141207.png

下载完成后,我将压缩包解压放在 d 盘的 soft 目录中。

环境变量

  • GRADLE_HOME

D:\soft\gradle-4.3-all

  • Path

    D:\soft\gradle-4.3-all\gradle-4.3\bin

参考资料

1、

2、

3、

4、


个人微信号:zhaoyanjun125 , 欢迎关注

weixin200.jpg

你可能感兴趣的文章
Python使用Mysql官方驱动(取出dict类型的数据)
查看>>
数据网格组件 Handsontable 不再开源,采用自拟的非商业许可证
查看>>
PostgreSQL 全文检索 - 词频统计
查看>>
这个“达芬奇”不一般!它是美国医生的好帮手
查看>>
Java中将List转成逗号数组的方案
查看>>
一如此前的回应,王劲将景驰科技总部搬到了广州
查看>>
Docker EE 2.0 版本震撼来袭,全新特性先睹为快(附资源地址)
查看>>
5月上海见-国际产学研专家集结第六届全球云计算大会中国站
查看>>
量子计算会带来什么样的革命?
查看>>
除了停电之外,今年的CES还有这些“意外”……
查看>>
多线程3,线程池封装库
查看>>
2016中国“互联网+”创业创新大赛(华北+东北)赛区决赛成功举办 5支优胜团队晋级海口总决赛...
查看>>
django 1.8 官方文档翻译: 1-1-2 快速安装指南
查看>>
FPGA设计中遇到的奇葩问题之“芯片也要看出身”(二)
查看>>
h.264 FMO
查看>>
SAP在阿里云白皮书-第三章 SAP上阿里云场景介绍
查看>>
asp.net C#后台实现下载文件的几种方法
查看>>
mysql之 xtrabackup原理、备份日志分析、备份信息获取
查看>>
线性查找算法(BFPRT)
查看>>
阿里云成为云原生计算基金会金牌会员
查看>>