转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/76408024
本文出自【赵彦军的博客】

系列目录

Android Gradle使用总结
Android Studio 插件开发详解一:入门练手
Android Studio 插件开发详解二:工具类
Android Studio 插件开发详解三:翻译插件实战
Android Studio 插件开发详解四:填坑
Android Gradle 自定义Task 详解
Android Gradle 自定义Task详解二:进阶

一:Gradle 是什么

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

关于 gradle 相关运用,可以移步 :Android Gradle使用总结

二:groovy 是什么

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

关于 groovy 相关知识,移步到这里: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 task
gradlew hello//执行 hello2 task
gradlew hello2//执行 hello3 task
gradlew hello3

五:创建Action

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

创建 Action 相关 API

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

小例子

build.gradle

//创建一个名字为hello的 task
task hello {//创建一个 Action , 添加到 Action 列表的头部doFirst(new Action<Task>() {@Overridevoid 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 task
tasks.create("hello2"){doFirst {println "hello2+++++"}
}
  • 自定义 DefaultTask 子类
class MyTask extends DefaultTask {@TaskActionvoid action(){println "action1+++++"}
}//创建 hello3 task
task 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之前先执行task1
task2.dependsOn task1

执行 task2

gradlew task2

执行效果

我是task1----
我是task2----

2、mustRunAfter

两个 task 依赖

task task1 << {println "我是task1----"
}task task2 << {println "我是task2----"
}//task2 运行之前先运行task1
task2.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 task1
task3.mustRunAfter task1
  • 执行 gradlew task1 task2 task3

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

  • 执行 gradlew task1 task3 task2

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

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

task1.mustRunAfter task2
task2.mustRunAfter task1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KlirwnPb-1604565137929)(http://o7rvuansr.bkt.clouddn.com/markdown_test_TIM截图20171102171717.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<Task>, 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' 不是内部或外部命令,也不是可运行的程序或批处理文件。

官网下载:http://services.gradle.org/distributions/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Ve6SQLU-1604565137931)(http://o7rvuansr.bkt.clouddn.com/markdown_test_TIM截图20171102141207.png)]

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

  • GRADLE_HOME

D:\soft\gradle-4.3-all

  • Path

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

参考资料

1、Android Gradle 必备实用技巧

2、Android Gradle使用总结

3、Groovy 使用完全解析

4、深入理解 Android Gradle 详解


个人微信号:zhaoyanjun125 , 欢迎关注
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RygbeYbg-1604565137933)(http://o7rvuansr.bkt.clouddn.com/weixin200.jpg)]

Android Gradle 自定义Task 详解相关推荐

  1. Android Gradle 自定义Task详解二:进阶

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78523958 本文出自[赵彦军的博客] 系列目录 Android Gradle使用 ...

  2. android自定义task,Android Gradle 自定义Task 详解

    一:Gradle 是什么 Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具. 它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于X ...

  3. android定义 task,Android Gradle 自定义Task 详解

    一:Gradle 是什么 Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具. 它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于X ...

  4. Android之自定义ContentProvider详解

    第一个版本  对android中MIME类型的理解 初始MIME类型,是在学习ContentProvider的时候. 当在创建自己的ContentProvider的时,需要从抽象类ContentPro ...

  5. android自定义dialog 例子,android dialog自定义实例详解

    本人工作有一个月多了.对于android很多东西,都有了新的了解或者说真正的掌握.为了让更多的像我这样的小白少走弯路,所以我会坚持将我在工作中遇到的一些比较令我印象深刻的知识点整合出来给大家(顺序是按 ...

  6. android button自定义样式详解,Android自定义格式显示Button的布局思路

    先把来源贴上 http://www.dibbus.com/2011/02/gradient-buttons-for-android/ 然后再让大家看看效果,这些都是xml布局文件实现的,一张图片都未曾 ...

  7. android 自定义xmlns,Android xmlns 的作用及其自定义实例详解

    Android xmlns 的作用及其自定义实例详解 xmlns:Android="http://schemas.android.com/apk/res/android的作用是: 这个是xm ...

  8. android ------- 开发者的 RxJava 详解

    在正文开始之前的最后,放上 GitHub 链接和引入依赖的 gradle 代码: Github:  https://github.com/ReactiveX/RxJava  https://githu ...

  9. build.gradle配置参数详解

    转载地址:http://blog.csdn.net/baidu_31093133/article/details/51860637 build.gradle配置参数详解//声明是Android程序ap ...

最新文章

  1. android列表实现置顶,Android利用RecyclerView实现全选、置顶和拖拽功能示例
  2. Golang用body来get或post数据
  3. 「Python」一文读懂装饰器
  4. golang实现生产者和消费者
  5. python网页爬虫例子_Python 利用Python编写简单网络爬虫实例3
  6. 可靠消息最终一致性设计_如何最终启动您的设计产品组合
  7. TCP状态转移:有限状态机
  8. docker network bridge模式,默认(一)
  9. mysql mvcc undo_Mysql Innodb中undo-log和MVCC多版本一致性读 的实现
  10. Android中Activity的启动模式和使用场景
  11. 基于Ghost框架搭建Blog
  12. 笔记本W10找不到端口(com口)及单片机串口连接的问题(附51开发板的CH340串口芯片的驱动程序安装包)
  13. HttpServletRequest--request.getParameter /getParameterValues/getParameterNames()/getParameterValues
  14. python技术--Linux基础01
  15. DeepFlow Large displacement optical flow with deep matching
  16. 负载均衡SLB和LVS的简单介绍
  17. GHM(anchor based)
  18. mplayer 播放电台_通过SSH的MPlayer从远程主机播放电影
  19. Amy-Tabb机器人世界手眼标定(4、Windows)
  20. 三级分销软件开发技术分销系统模式

热门文章

  1. servlrt程序的入口点是_刚刚,微信偷偷更新,小程序又放大招了!
  2. phantomjsjava_Java利用Phantomjs实现生成图片的功能
  3. 三十八、网络通信Socket模块实现文件传输
  4. 二十七、Kaggle| 研究生入学率预测
  5. kaggle机器学习 入门
  6. 十三、欧拉离散化计算期权定价期权定价
  7. 用状态空间法(卡尔曼滤波)解决深度高斯过程问题
  8. 直播 | AAAI 2021:文本对抗攻防中的对抗训练方法
  9. 面向睡眠阶段分类的自适应时空图卷积神经网络
  10. 知乎用户行为预测数据比赛,10万奖金等你来Battle!