当前位置: 首页 > news >正文

Gradle理论与实践—Gradle构建脚本基础

Gradle构建脚本基础

  • Project: 根据业务抽取出来的一个个独立的模块
  • Task:一个操作,一个原子性操作。比如上传一个jarmaven中心库等
  • Setting.gradle文件:初始化及整个工程的配置入口
  • build.gradle文件: 每个Project都会有个build.gradle的文件,是Project构建的入口。Root Project也有一个build.gradle文件,可以获取到所有的Child Project, 并且可以对所有的Child Project进行统一配置:如应用的三方插件、三方依赖库等。如,我们可以在Root Projectbuild.gradle文件里配置:
allprojects {repositories {jcenter()}
}

这样项目中所有依赖的三方库都可以在jcenter中下载了,省去了对每个Project去配置的情况。

上面用到的是allprojects,还可以配置subprojects,他们的区别在于:allprojects是对所有project的配置,包括Root Project。而subprojects是对所有Child Project的配置。更详细的请移步:https://blog.csdn.net/u013700502/article/details/85231687

1、创建一个task

Task的创建方式,可以是:

task hello {doFirst {print 'hello:doFirst\n'}doLast {print 'hello:doLast\n'}
}

也可以是:

tasks.create("hello") {doFirst {print 'hello:doFirst'}doLast {print 'hello:doLast'}
}

他们执行的结果都是一样的:

bogon:test_gradle mq$ gradle -q hello
hello:doFirst
hello:doLast

task是Project对象的一个函数,原型为Task create(String name, Closure configureClosure),最后一个参数是闭包的时候,可以放到括号外面,并且括号可以省略,task中的doFirstdoLast分别在任务前后执行。

如需完整版Gradle学习资料 请点击免费领取

2、创建Task的几种方式

  • 1、调用Project对象的task(String name)方法,如:
def Task hello = task(hello);hello << {print 'hello\n'
}

输出:

bogon:test_gradle mq$ gradle -q hello
hello
  • 2、任务名字+闭包方式,如:
task hello {description '任务描述'doLast {print "方法原型: Task task(String name, Closure configureClosure)\n"print "任务描述: ${description}"}
}

输出结果:

bogon:test_gradle mq$ gradle -q hello
方法原型: Task task(String name, Closure configureClosure)
任务描述: 任务描述
  • 3、TaskContainer方式创建:
tasks.create('hello') {description '任务描述'doLast {print "方法原型: Task create(String name, Closure configureClosure)\n"print "任务描述: ${description}"}
}

输出结果:

方法原型: Task create(String name, Closure configureClosure)
任务描述: 任务描述

tasks是Project的属性,其类型是TaskContainer。其中1和2的创建最终也是调用TaskContainer方式创建的。

3、Task内部执行顺序

当我们执行Task的时候,就是执行其拥有的actions列表,是一个List。把Task执行之前、Task本身执行、Task之后执行分别称为doFirst、doSelf、doLast,先来看个例子:

def Task hello = task myTask(type: CustomTask);hello.doFirst {print 'Task执行之前 do-First\n'
}hello.doLast {print 'Task执行之后 do-Last\n'
}class CustomTask extends DefaultTask {@TaskActiondef doself() {print 'Task执行自身 do-self\n'}
}

输出:

bogon:test_gradle mq$ gradle -q hello
Task执行之前 do-First
Task执行自身 do-self
Task执行之后 do-Last

通过结果发现确实是按照我们想要的顺序执行的。Gradle在执行hello这个任务的时候,Gradle会解析其带有@TaskAction注解的方法作为其Task执行的Action,并且把其加入到actionList中。而doFirst、doLast分别会在actionList的最前面和最后面加入,所以之后就达到了按顺序执行。

4、Task任务依赖

任务之间是可以有依赖关系的,使用dependsOn执行当前task依赖的任务,如:

task hello << {print 'hello '
}task world(dependsOn: hello) {doLast {print 'world'}}

此时执行gradle -q world,结果如下:

bogon:test_gradle mq$ gradle -q world
hello world

因为world任务是依赖hello的,所以当执行world后,先去执行了hello任务,再执行world任务。dependsOn是Task类的一个方法,可以接受多个依赖的任务作为参数。 修改以下程序:

task hello << {print 'hello\n'
}task world(dependsOn: hello) {doLast {print 'world\n'}
}world.doFirst {print 'doFirst\n'
}world.doLast {print 'doLast2\n'
}

结果:

bogon:test_gradle mq$ gradle -q world
hello
doFirst
world
doLast2

通过结果可以看出,doFirst和doLast可以使用多次,并且按顺序执行doLast可以用 << 操作符替代。

5、自定义属性

ProjectTask允许添加额外自定义属性,通过对应的ext属性即可,如

//自定义一个Project的属性
ext.buildTime = '2018'//自定义多个属性
ext {buildTime = '2018'month = '12'
}task time {doLast {print "构建时间${buildTime} 年${month}月 \n"}
}

执行gradle -q time,执行结果:

bogon:test_gradle mq$ gradle -q time
构建时间201812

可见我们自定义的属性正确地取到了,自定义属性的作用域很广,只要能得到对应的Project,就能获取到定义的属性值。在Android中我们通常使用自定义属性值来定义我们的版本号、版本名称等,把这些放到一个单独的gradle文件中,因为他们在发版前就会变动,放到单独的gradle文件中便于管理,在AS根目录下新建config.gradle如下:

//config.gradle
ext {android = [compileSdkVersion: 26,buildToolsVersion: "25.0.0",versionName      : "6.2.1",versionCode      : 6210,minSdkVersion    : 16,targetSdkVersion : 23]}

APP对应的build.gradle中取值:

//build.gradle
apply from: rootProject.getRootDir().getAbsolutePath() + '/config.gradle'compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion

就可以获取到自定义的属性值。

上例中,除了能获取到config.gradle中的属性值,还可以在build.gradle中调用config.gradle中的方法,具体实现:

//config.gradle
ext {.......其他.........//注意方法和属性写法的区别copyApk = this.&copyApk
}def copyApk() {}

build.gradle调用:

//build.gradle
apply from: rootProject.getRootDir().getAbsolutePath() + '/config.gradle'copyApk()

这样就实现了在build.gradle中调用config.gradle中的copyApk()方法了。

相关文章:

Gradle理论与实践—Gradle构建脚本基础

Gradle构建脚本基础 Project: 根据业务抽取出来的一个个独立的模块Task&#xff1a;一个操作&#xff0c;一个原子性操作。比如上传一个jar到maven中心库等Setting.gradle文件&#xff1a;初始化及整个工程的配置入口build.gradle文件: 每个Project都会有个build.gradle的文件…...

【Vue 基础】vue-cli初始化项目及相关说明

目录 1. 创建项目 2. 项目文件介绍 3. 项目的其它配置 3.1 项目运行时&#xff0c;让浏览器自动打开 3.2 关闭eslint校验功能 3.3 src文件夹简写方法 1. 创建项目 vue create 项目名 2. 项目文件介绍 创建好的项目中包含如下文件&#xff1a; &#xff08;1&#xff09…...

【c语言】详解c语言#预处理期过程 | 宏定义前言

c语言系列专栏&#xff1a; c语言之路重点知识整合 创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持…...

内网远程控制软件哪个好用

市面上远程控制软件很多&#xff0c;但是支持纯内网环境&#xff08;无外网&#xff09;的很少。大部分远程控制软件可以在局域网用&#xff0c;但是它的数据流量还是要走软件公司服务器&#xff0c;也就是要走外网&#xff0c;所以在纯内网环境没法使用。那么什么软件支持纯内…...

【计算机基本原理-数据结构】数据结构中树的详解

【计算机基本原理-数据结构】数据结构中树的详解 1&#xff09;总览2&#xff09;树的相关概念3&#xff09;二叉树、满二叉树、完全二叉树4&#xff09;二叉查找树 - BST5&#xff09;平衡二叉树 - AVL6&#xff09;红黑树7&#xff09;哈弗曼树8&#xff09;B 树9&#xff09…...

数字设计小思 - D触发器与死缠烂打的亚稳态

前言 本系列整理数字系统设计的相关知识体系架构&#xff0c;为了方便后续自己查阅与求职准备。在FPGA和ASIC设计中&#xff0c;D触发器是最常用的器件&#xff0c;也可以说是时序逻辑的核心&#xff0c;本文根据个人的思考历程结合相关书籍内容和网上文章&#xff0c;聊一聊D…...

Notes/Domino 11.0.1FP7以及在NAS上安装Domino等

大家好&#xff0c;才是真的好。 目前HCL在还是支持更新的Notes/Domino主要是三个版本&#xff0c;V10、11和12&#xff0c;这不,上周HCL Notes/Domino 11.0.1居然推出了FP7补丁包程序。 从V10.0.1开始&#xff0c;Domino的FP补丁包程序主要是用来修复对应主要版本中的一些问…...

【VM服务管家】VM4.x算子SDK开发_3.3 模块工具类

目录 3.3.1 位置修正&#xff1a;位置修正算子工具的使用方法3.3.2 模板保存&#xff1a;实现模板自动加载的方法3.3.3 模板匹配&#xff1a; 获取模板匹配框和轮廓点的方法3.3.4 模板训练&#xff1a;模板训练执行完成的判断方法3.3.5 图像相减&#xff1a;算子SDK开发图像相减…...

Aspose.Pdf使用教程:在PDF文件中添加水印

Aspose.PDF 是一款高级PDF处理API&#xff0c;可以在跨平台应用程序中轻松生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现&#xff0c;保护和打印文档。无需使用Adobe Acrobat。此外&#xff0c;API提供压缩选项&#xff0c;表创建和处理&#xff0c;图形和图像功能&am…...

H.264/AVC加密----选择加密

文献学习&#xff1a; 《Data Hiding in Encrypted H.264/AVC Video Streams by Codeword Substitution》 期刊&#xff1a;IEEE TRANSACTIONS ON INFORMATION FORENSICS AND SECURITY 简介 通过分析H.264/AVC编解码器的特性&#xff0c;提出了三个敏感部分(IPM、MVD和残差系…...

WuThreat身份安全云-TVD每日漏洞情报-2023-04-26

漏洞名称:Google Android 命令注入漏洞 漏洞级别:高危 漏洞编号:CVE-2023-20964,CNNVD-202303-538 相关涉及:None 漏洞状态:POC 参考链接:https://tvd.wuthreat.com/#/listDetail?TVD_IDTVD-2023-05794 漏洞名称:OpenSSL RSA 解密时间差异 漏洞级别:中危 漏洞编号:CVE-2022-4…...

剑指 Offer第二版:1~n 整数中 1 出现的次数、51. 数组中的逆序对、56 - II. 数组中数字出现的次数 II

剑指 Offer第二版 43. 1&#xff5e;n 整数中 1 出现的次数51. 数组中的逆序对56 - II. 数组中数字出现的次数 II 43. 1&#xff5e;n 整数中 1 出现的次数 题目&#xff1a;输入一个整数 n &#xff0c;求1&#xff5e;n这n个整数的十进制表示中1出现的次数。 例如&#xff0c…...

云原生-k8s核心概念(pod,deploy,service,ingress,configmap,volume)

Gitee-k8s学习 云原生实战-kubernetes核心实战 namespace Namespace是kubernetes系统中的一种非常重要资源&#xff0c;它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离 Pod Pod可以认为是容器的封装&#xff0c;一个Pod中可以存在一个或者多个容器。 De…...

他工作10年,老板却让他走人

大家好&#xff0c;我是五月&#xff0c;一个编程街溜子。 二狗被裁了&#xff0c;他在公司待了快十年&#xff0c;他想留下来&#xff0c;老板却让他走。 我和他一样困惑。 他985毕业&#xff0c;工作中有从0开始一个项目直到日活过千万&#xff0c;也有过参与顶级产品核心…...

vpp怎么写node

VPP&#xff08;Vector Packet Processing&#xff09;是一个高性能的数据平面开源项目&#xff0c;用于构建网络功能虚拟化&#xff08;NFV&#xff09;和软件定义网络&#xff08;SDN&#xff09;解决方案。它由Cisco开发&#xff0c;并在Apache 2.0许可下发布。 在VPP中&am…...

【4. ROS的主要通讯方式:Topic话题与Message消息】

【4. ROS的主要通讯方式&#xff1a;Topic话题与Message消息】 1. 前言1.1 王者解释结点通讯&#xff1a;1.2 通讯小结 2. 灵活的Topic话题图解2.1 话题注意细节2.2 外延补充 3. Message消息图解3.1 消息类型3.2 查看标准消息类型std_msgs 4. 使用C实现Publisher发布者4.1 发布…...

【react全家桶学习】react中组件定义及state属性(超详/必看)

函数式组件定义及特点 定义&#xff08;核心就是一个函数&#xff0c;返回虚拟dom&#xff09;&#xff1a; import React from reactexport default function index() {return <div>index</div> }特点&#xff1a; 1、适用于【简单组件】的定义2、是一个函数&a…...

如何以产品经理思维打造一所高品质学校?

学校的建设与管理真不是一件容易事。2023年03月17日&#xff0c;山东菏泽市曹县一家长投诉某中学课业繁重&#xff0c;孩子经常写作业到半夜&#xff1b;2023年4月4日&#xff0c;张先生在华龙网重庆网络问政平台投诉万州区某中学伙食差&#xff0c;指出“发灰的洋葱&#xff0…...

根治Spring中使用Mongo时报错InvalidMongoDbApiUsageException

文章目录 And Or迷惑原因 告别InvalidMongoDbApiUsageException问题简单解决根本解决修改源码 代码(省流&#xff0c;可以直接看这里&#xff09; And Or 很多时候都需要进行逻辑的与或操作&#xff0c;但是spring当中自带的操作并不好用&#xff0c;于是做了相关的改进&#…...

【计算机组成原理】数据的表示和运算·进位计数制

&#x1f6a9; 本文已收录至专栏&#xff1a;计算机基础 我们可以通过显示屏看到各种形式的数据信息&#xff0c;但数据是如何在计算机中表示呢&#xff1f;运算器又是如何实现数据的算数、逻辑运算&#xff1f; 十进制数是最适合我们日常使用的一种计数方式&#xff0c;除此之…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...

基于单片机的宠物屋智能系统设计与实现(论文+源码)

本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢&#xff0c;连接红外测温传感器&#xff0c;可实时精准捕捉宠物体温变化&#xff0c;以便及时发现健康异常&#xff1b;水位检测传感器时刻监测饮用水余量&#xff0c;防止宠物…...

js 设置3秒后执行

如何在JavaScript中延迟3秒执行操作 在JavaScript中&#xff0c;要设置一个操作在指定延迟后&#xff08;例如3秒&#xff09;执行&#xff0c;可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法&#xff0c;它接受两个参数&#xff1a; 要执行的函数&…...