热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android自定义task,AndroidGradle自定义Task详解

转载请标明出处:http:blog.csdn.netzhaoyanjun6articledetails76408024本文出自【赵彦军的博客】一:Gra

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

@Override

void execute(Task task) {

println "action1++++++++++"

}

})

//创建一个 Action , 添加到 Action 列表的头部

doFirst {

println "action2++++++++++"

}

}

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

6c1555302777729326ca3efa0910d9ec.png

运行 hello task : gradle hello

运行结果:

action2++++++++++

action1++++++++++

leftShift 说明

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

build.gradle

task hello {

//在 Action 列表尾部添加一个 Action

leftShift {

println "+++++"

}

}

leftShift 还有一种简洁写法&#xff0c;用 <<代替, 如下所示&#xff1a;

build.gradle

task hello <

//在 Action 列表尾部添加一个 Action

println "&#43;&#43;&#43;&#43;&#43;"

}

那么问题来了&#xff0c;task 中的 Action 在什么时候执行&#xff1f;

六&#xff1a;Gradle 生命周期

1.初始化阶段

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

2.配置阶段

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

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

3.运行阶段

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

七&#xff1a;创建 Task 的另外一种方式

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

tasks

build.gradle

//创建 hello2 task

tasks.create("hello2"){

doFirst {

println "hello2&#43;&#43;&#43;&#43;&#43;"

}

}

自定义 DefaultTask 子类

class MyTask extends DefaultTask {

&#64;TaskAction

void action(){

println "action1&#43;&#43;&#43;&#43;&#43;"

}

}

//创建 hello3 task

task hello3 (type: MyTask){

doLast{

println "action2&#43;&#43;&#43;&#43;&#43;"

}

}

运行 hello3 task&#xff1a;gradlew hello3

输出

action1&#43;&#43;&#43;&#43;&#43;

action2&#43;&#43;&#43;&#43;&#43;

八&#xff1a; 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----

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

task1.mustRunAfter task2

task2.mustRunAfter task1

6c1555302777729326ca3efa0910d9ec.png

3、shouldRunAfter

形成依赖关系可有可无。

build.gradle

task task1 <<{

println "我是task1----"

}

task task2 <<{

println "我是task2----"

}

task1.shouldRunAfter task2

运行&#xff1a; gradlew task1 task2

我是task2----

我是task1----

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

九&#xff1a;系统默认 task

gradle 默认提供了很多 task 给我们使用&#xff0c;比如 copy、delete

1、copy

build.gradle

task 任务的名字 (type: Copy) {

//action

}

Api 介绍

//数据源目录&#xff0c;多个目录

public AbstractCopyTask from(Object... sourcePaths)

//目标目录&#xff0c;单一

public AbstractCopyTask into(Object destDir)

//过滤文件 包含

public AbstractCopyTask include(String... includes)

//过滤文件 排除

public AbstractCopyTask exclude(String... excludes)

//重新命名&#xff0c;老名字 新名字

public AbstractCopyTask rename(String sourceRegEx, String replaceWith)

//删除文件 Project 接口

boolean delete(Object... paths);

小例子&#xff1a;

复制图片&#xff1a;单一数据源

task copyImage(type: Copy) {

from &#39;C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy&#39;

into &#39;C:\\Users\\yiba_zyj\\Desktop&#39;

}

复制图片&#xff1a;多个数据源

task copyImage(type: Copy) {

from &#39;C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy&#39; ,

&#39;C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy&#39;

into &#39;C:\\Users\\yiba_zyj\\Desktop&#39;

}

复制图片&#xff1a;过滤文件

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

task copyImage(type: Copy) {

from &#39;C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy&#39;

into &#39;C:\\Users\\yiba_zyj\\Desktop&#39;

include "*.jpg"

}

复制文件&#xff1a;过滤文件&#xff0c;重命名

task copyImage(type: Copy) {

from &#39;C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy&#39;

into &#39;C:\\Users\\yiba_zyj\\Desktop&#39;

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 &#39;../aaa&#39;

}

删除桌面上的文件

build.gradle

task deleteFile(type: Delete) {

//删除系统桌面 delete

delete "C:\\Users\\yiba_zyj\\Desktop\\gradle\\delete"

}

十&#xff1a;小技巧

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

build.gradle

task deleteFile{

//do some things

}

运行

gradlew dF 等价 gradlew deleteFile

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

2、常见的 gradlew 命令

查看项目所有默认自带的 task&#xff0c;不包括自定义 task

gradlew tasks

查看所有 task (默认 task &#43; 自定义task)

gradlew tasks --all

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

gradlew help --task taskName

查看 gradle 版本

gradlew -version

3、给task 添加描述 description

task task1 <<{

description &#61; "这是一段描述信息"

println "我是task1----"

}

十一&#xff1a;Gradle 环境变量配置

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

&#39;gradle&#39; 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。

官网下载&#xff1a;http://services.gradle.org/distributions/

6c1555302777729326ca3efa0910d9ec.png

下载完成后&#xff0c;我将压缩包解压放在 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 详解

个人微信号&#xff1a;zhaoyanjun125 , 欢迎关注

6c1555302777729326ca3efa0910d9ec.png

来源&#xff1a;https://www.cnblogs.com/zhaoyanjun/p/7988965.html



推荐阅读
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • 本文讨论了在shiro java配置中加入Shiro listener后启动失败的问题。作者引入了一系列jar包,并在web.xml中配置了相关内容,但启动后却无法正常运行。文章提供了具体引入的jar包和web.xml的配置内容,并指出可能的错误原因。该问题可能与jar包版本不兼容、web.xml配置错误等有关。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
author-avatar
手机用户2502869561
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有