Android Gradle 自定义Task 详解
转载请标明出处: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 相关运用,可以移步 :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 队列头部添加Action
Task doFirst(Action<? super Task> action);
Task doFirst(Closure action);
//在Action 队列尾部添加Action
Task doLast(Action<? super Task> action);
Task doLast(Closure action);
//已经过时了,建议用 doLast 代替
Task leftShift(Closure action);
//删除所有的Action
Task deleteAllActions();
小例子
build.gradle
//创建一个名字为hello的 task
task hello {
//创建一个 Action , 添加到 Action 列表的头部
doFirst(new Action<Task>() {
@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 task
tasks.create("hello2"){
doFirst {
println "hello2+++++"
}
}
- 自定义 DefaultTask 子类
class MyTask extends DefaultTask {
@TaskAction
void 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

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/

下载完成后,我将压缩包解压放在 d 盘的 soft 目录中。
环境变量
- GRADLE_HOME
D:\soft\gradle-4.3-all
- Path
D:\soft\gradle-4.3-all\gradle-4.3\bin
参考资料
个人微信号:zhaoyanjun125 , 欢迎关注

Android Gradle 自定义Task 详解的更多相关文章
- Gradle技术之四 - Gradle的Task详解
1 Gradle的Task详解 1 Task定义和配置 2 Task的执行 3 Task的依赖和执行顺序 4 Task类型 5 Task结合gradle的生命周期 6 Task实战 1.1 Task定 ...
- Android 自定义 View 详解
View 的绘制系列文章: Android View 绘制流程之 DecorView 与 ViewRootImpl Android View 的绘制流程之 Measure 过程详解 (一) Andro ...
- 【转载】Android Studio Service AIDL 详解
公司产品之前IM这块存在很多问题,消息到达率低,加上协议上有些问题,丢消息频繁,所以需要重构IM,AIDL不能解决以上问题.好吧!那AIDL可以解决什么问题?什么是AIDL? 什么是AIDL? AID ...
- Android开发之InstanceState详解
Android开发之InstanceState详解 本文介绍Android中关于Activity的两个神秘方法:onSaveInstanceState() 和 onRestoreInstanceS ...
- 给 Android 开发者的 RxJava 详解
我从去年开始使用 RxJava ,到现在一年多了.今年加入了 Flipboard 后,看到 Flipboard 的 Android 项目也在使用 RxJava ,并且使用的场景越来越多 .而最近这几个 ...
- Android开发之InstanceState详解(转)---利用其保存Activity状态
Android开发之InstanceState详解 本文介绍Android中关于Activity的两个神秘方法:onSaveInstanceState() 和 onRestoreInstanceS ...
- android ------- 开发者的 RxJava 详解
在正文开始之前的最后,放上 GitHub 链接和引入依赖的 gradle 代码: Github: https://github.com/ReactiveX/RxJava https://github. ...
- 转:给 Android 开发者的 RxJava 详解
转自: http://gank.io/post/560e15be2dca930e00da1083 评注:多图解析,但是我还是未看懂. 前言 我从去年开始使用 RxJava ,到现在一年多了.今年加入 ...
- ANDROID L——Material Design详解(UI控件)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...
随机推荐
- android dataBinding详解
官方介绍地址:http://developer.android.com/intl/zh-cn/tools/data-binding/guide.html 2015 Google IO 大会带来的 Da ...
- java虚拟机构造原理
Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序.程序开始执行时他才运行,程序结束时他就停止.你在同一台机器上运行三个程序,就会有三个运行中的Java虚拟机. ...
- [RDLC]一步一步教你使用RDLC(一)
一:加数据集,并且命名为Quotation,如下图所示: 二: 添加一张报表,命名为Quotation,如下图所示: 向报表中添加"表"这一项,如下图所示: 这时就弹出一个选择数据 ...
- python +Django 搭建web开发环境初步,显示当前时间
1.python 的安装 网上很多关于django跟python 开发的资料,这块我正在实习准备用这个两个合起来搞一个基于web 的东西出来现在开始学习,写点东西记录一下心得. 开发环境是window ...
- Swift基础之UITableView(之前写的知识点都是最新的2.2版本样式,欢迎大家参考,可以相互交流)
//这里只是列举了经常使用的UITableView的属性和方法,其他的都可以类似使用,注意用法即可 //设置全局变量UITableView var myTableView = UITa ...
- RHEL6从源码安装python及其他软件包
RHEL6从源码安装python及其他软件包 ## install ssl $ sudo yum install openssl-devel or: $ sudo apt-get install li ...
- 《java入门第一季》之面向对象(构造方法)
/* 构造方法: 给对象的数据进行初始化 格式: A:方法名与类名相同 B:没有返回值类型,连void都没有 C:没有具体的返回值 */ class Student { private String ...
- DB Query Analyzer 6.03, the most excellent Universal DB Access tools on any Microsoft Windows OS
DB Query Analyzer 6.03, the most excellent Universal database Access tools on any Microsoft Wind ...
- 【Linux 操作系统】vim编辑器配置及常用命令
最近工作不安分, 没有了刚入行时候的锐气, 不知道什么时候开始懈怠起来, 周末在电脑旁边看新闻, 搞笑图片, 追美剧, 一坐就是一天, 很是空虚. 我需要摆脱这种状态, 正好想学习一下安卓底层, An ...
- SpriteBuilder弹出菜单层造成卡顿的解决办法
如果你注意到略微的卡顿(延时)(lag due to low framerate)当显示一个全屏的弹出菜单时,你可以简单的设置_levelNode(_levelNode是主游戏界面中的背景层,所有游戏 ...