转载请标明出处: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

参考资料

1、Android Gradle 必备实用技巧

2、Android Gradle使用总结

3、Groovy 使用完全解析

4、深入理解 Android Gradle 详解


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

Android Gradle 自定义Task 详解的更多相关文章

  1. Gradle技术之四 - Gradle的Task详解

    1 Gradle的Task详解 1 Task定义和配置 2 Task的执行 3 Task的依赖和执行顺序 4 Task类型 5 Task结合gradle的生命周期 6 Task实战 1.1 Task定 ...

  2. Android 自定义 View 详解

    View 的绘制系列文章: Android View 绘制流程之 DecorView 与 ViewRootImpl Android View 的绘制流程之 Measure 过程详解 (一) Andro ...

  3. 【转载】Android Studio Service AIDL 详解

    公司产品之前IM这块存在很多问题,消息到达率低,加上协议上有些问题,丢消息频繁,所以需要重构IM,AIDL不能解决以上问题.好吧!那AIDL可以解决什么问题?什么是AIDL? 什么是AIDL? AID ...

  4. Android开发之InstanceState详解

    Android开发之InstanceState详解   本文介绍Android中关于Activity的两个神秘方法:onSaveInstanceState() 和 onRestoreInstanceS ...

  5. 给 Android 开发者的 RxJava 详解

    我从去年开始使用 RxJava ,到现在一年多了.今年加入了 Flipboard 后,看到 Flipboard 的 Android 项目也在使用 RxJava ,并且使用的场景越来越多 .而最近这几个 ...

  6. Android开发之InstanceState详解(转)---利用其保存Activity状态

    Android开发之InstanceState详解   本文介绍Android中关于Activity的两个神秘方法:onSaveInstanceState() 和 onRestoreInstanceS ...

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

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

  8. 转:给 Android 开发者的 RxJava 详解

    转自:  http://gank.io/post/560e15be2dca930e00da1083 评注:多图解析,但是我还是未看懂. 前言 我从去年开始使用 RxJava ,到现在一年多了.今年加入 ...

  9. ANDROID L——Material Design详解(UI控件)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...

随机推荐

  1. sublime test2 快捷键

    快捷键比较全的:http://blog.useasp.net/archive/2013/06/14/sublime-text-2-all-default-Shortcuts-table-on-wind ...

  2. 使用go reflect实现一套简易的rpc框架

    go jsonrpc 在实际项目中,我们经常会碰到服务之间交互的情况,如何方便的与远端服务进行交互,就是一个需要我们考虑的问题. 通常,我们可以采用restful的编程方式,各个服务提供相应的web接 ...

  3. 自定义gradle的property

    在android studio上运行项目,gradle的配置是必不可少的,但是随着项目的逐渐成长,迎面而来的就是.各种依赖包的添加,数不胜数的签名,渠道包等,整个gradle变得很乱,这样其实我们可以 ...

  4. Android官方技术文档翻译——构建工作流

    本文译自androd官方技术文档<Build Workflow>,原文地址:http://tools.android.com/tech-docs/new-build-system/buil ...

  5. UIViewController/ApplicationSequ…

    UIViewController   ApplicationSequence UI-03 注意: NSLog(@"%s %d",__FUNCTION__,__LINE__); // ...

  6. 9.7、Libgdx之振动器

    (官网:www.libgdx.cn) 振动器允许你提醒手机用户. 振动器智能应用在Android设备中,需要特殊的权限: android.permission.VIBRATE 可以通过如下方式实现振动 ...

  7. 安卓TV开发(三) 移动智能设备之实现主流TV电视盒子焦点可控UI

    前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验上有很大的区别,本系列博文主 ...

  8. 《java入门第一季》之面向对象(继承总结)

    继承已经全部写完了,接下来通过几个案例对继承问题做一个总结: /* 看程序写结果: A:成员变量 就近原则 B:this和super的问题 this访问本类的成员 super访问父类的成员 C:子类构 ...

  9. CCRenderBuffer初始化中的render state参数

    绘制纹理三角形的渲染状态(render state)已经被CCSprite基类设置过了,所以你可以简单的将self.renderState传递过去就可以了. 渲染状态是混合模式(blend mode) ...

  10. VCC、 VDD、VEE、VSS 电压理解

    VCC. VDD.VEE.VSS 版本一: 简单说来,可以这样理解: 一.解释 VCC:C=circuit 表示电路的意思, 即接入电路的电压: VDD:D=device 表示器件的意思, 即器件内部 ...