Android Gradle 自定义Task 详解

简介: 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/76408024 本文出自【赵彦军的博客】 一:Gradle 是什么Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具。

转载请标明出处: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 , 欢迎关注

相关文章
|
1月前
|
Android开发
Android基于gradle task检查各个module之间资源文件冲突情况
Android基于gradle task检查各个module之间资源文件冲突情况
Android基于gradle task检查各个module之间资源文件冲突情况
|
1月前
|
Android开发 开发者
安卓应用开发中的自定义视图
【9月更文挑战第37天】在安卓开发的海洋中,自定义视图犹如一座座小岛,等待着勇敢的探索者去发现其独特之处。本文将带领你踏上这段旅程,从浅滩走向深海,逐步揭开自定义视图的神秘面纱。
38 3
|
1月前
|
数据可视化 Android开发 开发者
安卓应用开发中的自定义View组件
【10月更文挑战第5天】在安卓应用开发中,自定义View组件是提升用户交互体验的利器。本篇将深入探讨如何从零开始创建自定义View,包括设计理念、实现步骤以及性能优化技巧,帮助开发者打造流畅且富有创意的用户界面。
76 0
|
13天前
|
搜索推荐 前端开发 Android开发
安卓应用开发中的自定义视图实现
【10月更文挑战第30天】在安卓开发的海洋中,自定义视图是那抹不可或缺的亮色,它为应用界面的个性化和交互体验的提升提供了无限可能。本文将深入探讨如何在安卓平台创建自定义视图,并展示如何通过代码实现这一过程。我们将从基础出发,逐步引导你理解自定义视图的核心概念,然后通过一个实际的代码示例,详细讲解如何将理论应用于实践,最终实现一个美观且具有良好用户体验的自定义控件。无论你是想提高自己的开发技能,还是仅仅出于对安卓开发的兴趣,这篇文章都将为你提供价值。
|
15天前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
28 5
|
1月前
|
Android开发
Android gradle task任务检查各个module之间资源文件冲突.md
Android gradle task任务检查各个module之间资源文件冲突.md
Android gradle task任务检查各个module之间资源文件冲突.md
|
1月前
|
XML 前端开发 Java
安卓应用开发中的自定义View组件
【10月更文挑战第5天】自定义View是安卓应用开发的一块基石,它为开发者提供了无限的可能。通过掌握其原理和实现方法,可以创造出既美观又实用的用户界面。本文将引导你了解自定义View的创建过程,包括绘制技巧、事件处理以及性能优化等关键步骤。
|
1月前
|
Java Android开发 Windows
玩转安卓之配置gradle-8.2.1
为安卓开发配置Gradle 8.2.1,包括下载和解压Gradle、配置环境变量、修改配置文件以增加国内镜像,以及在Android Studio中配置Gradle和JDK的过程。
73 0
玩转安卓之配置gradle-8.2.1
|
5天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
6天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。