Android Gradle使用详解(一) 之 Gradle基础

xiaoxiao2025-10-12  14

1 简介

Gradle是一款非常优秀的构建系统工具,它是一门专门解决自动化构建的DSL(Domain Specifice Language,领域特定语言)。它的实现基于Groovy(Groovy是一种基于JVM虚拟机的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy它的语法和Java非常相似,能够与 Java 代码很好地结合和扩展)。

2 环境

Gradle的官网下载页地址是:https://services.gradle.org/distributions/。一般地下载完后将其解压放于C:\Program Files\Android\gradle-x.x.x中,我们可以看到如下目录清单:

bin docs                                       -- API、DSL、指南等文档 init.d                                       -- gradle的初始化脚本目录 lib                                           -- 相关库 media                                     -- 一些icon资源 samples                                 -- 示例 src                                         -- 源文件 getting-started.html               -- 入门链接 LICENSE NOTICE

要运行Gradle,必须把bin目录添加到环境变量PATH的路径里才可以。添加后要验证配置是否正常,我们只需要在命令窗口中输入gradle –v命令查看即可(若不行请重启电脑)。

3 Hello World

新建一目录,如:gradle_hello_world,然后就该目录下创建一个名为build.gradle的文件,文件内容如下:

task hello{          doLast{                    println'Hello World!'          } }

命令窗口中运行gradle –q hello命令来执行构造脚本,输出:

说明:

1、build.gradle就Gradle默认的构建脚本,执行Gradle命令时会默认加载当前目录下的build.gradle脚本文件。

2、这个脚本定义一个任务(Task),任务名叫hello,并且给任务hello添加一个动作(Action),其实它就是一段Groovy语言实现的闭包。doLast意味着在Task执行完毕后要回调doLast的这部分闭包的代码实现。

3、因为Groovy已经把println()方法添加到java.lang.Object,而在Groovy中,方法的调用可省略括号,以一个空格分开即可;还有一点,在Groovy中单引号和双引号的内容都是字答串,不区分字符和字符串,但是单引号标记的是纯粹字符串常量,而不能参与表达式运算。

4、命令gradle –q hello中,-q参数用于控制gradle输出的日志级别。gradle的日志级别有:

    ERROR            错误信息     QUIET              重要消息     WARNING        警告消息     LIFECYCLE     进度消息     INFO                信息消息     DEBUG            调试信息

5、另外,除了日志级别参数外,还可以通过-s(关键性的堆栈信息)或-S(全部堆栈信息)来打印出堆栈信息

4 Gradle Wrapper

Wrappe是对Gradle的一层包装,便于团队开发过程中统一Gradle构建的版本。当我们使用Wrapper启动Gradle时,Wrapper会检查Gradle有没有被下载关联,如果没有将会配置的地址(一般是Gradle官方库)进行下载并运行构建。只要执行Wrapper命令,它会帮你搞定一切。这种方式也方便我们在服务器上做持续集成。

4.1 生成Wrapper

在命令窗口中输入:gradle wrapper(默认当前电脑版本) 或 gradle wrapper –gradle-version x.x(指定版本),便生成如下图文件:

文件说明:

文件gradlew和gradlew.bat分别是Linux和Windows下的可执行脚本,它们的用法和Gradle原生命令是一样的。

文件夹gradle下有两件文件:gradle\wrapper\gradle-wrapper.jar 和 gradle\wrapper\gradle-wrapper.properties。其中,gradle-wrapper.jar是具体业务逻辑实现的jar包,gradlew最终还是使用Java执行这个jar包来执行相关Gradle操作,而gradle-wrapper.properties是配置文件,用于配置Gradle信息。

gradle-wrapper.properties它的内容如下图所示:

配置中字段说明:

distributionBase         下载的Gradle压缩包解压后存储的主目录 distributionPath          相对于distributionBase的解压后的Gradle压缩包的路径 zipStoreBase             同distributionBase,只不过是存放zip压缩包的 zipStorePath              同distributionPath,只不过是存放zip压缩包的 distributionUrl            Gradle发行版压缩包的下载地址。通常地会将distributionUrl 中的bin改为all,这样在开发过程中,就可以看到Gradle的源代码。另外,如若总是下载失败,可以考虑将https替换成http。

4.2 自定义Wrapper Task

也可以通过task来自定义gradle-wrapper.properties的字段信息,如个修改build.gradle文件,并运行命令:gradle wrapper

task hello{ doLast{ println'Hello World!' } } task wrapper(type:Wrapper) { gradleVersion = '4.2.1' archiveBase='GRADLE_USER_HOME' archivePath='wrapper/dists' distributionBase='GRADLE_USER_HOME' distributionPath='wrapper/dists' distributionUrl='http://services.gradle.org/distributions/gradle-4.2.1-all.zip' }

5 Groovy关键语法

5.1 分号

Groovy中,分号是可写可不写的。

5.2 字符串

Groovy中,单引号和双引号都可以定义字符串常量,不同的是单引号标记的是纯粹字符串常量,而不是对字符串里的表达式做运算,但双引号可以。如使用“+”连接两个字符串,就一定得使用双引号。

5.3 集合

List

Groovy中,使用ArrayList就像使用普通数组一样,修改hello world示例代码如下:

task hello{ println'Hello World!' def numList = [1,2,3,4,5]; println'----------ArrayList class name:' println numList.getClass().name; println'----------ArrayList element:' println numList[1] // 访问第二个元素 println numList[-1] // 访问最后一个元素 println numList[0..2] // 访问第1到第3个元素 println'----------ArrayList each:' numList.each{ println it; } }

运行结果:

Map

来看看map的使用示例,同样修改hello world示例代码如下:

task hello{ println'Hello World!' def mapSizp = ['width':1920, 'height': 1080]; println'----------LinkedHashMap class name:' println mapSizp.getClass().name; println'----------LinkedHashMap element:' println mapSizp['width']; println mapSizp.height; println'----------LinkedHashMap each:' mapSizp.each{ println "Key:${it.key},Value:${it.value}"; } }

运行结果: 

5.4方法

方法的写法很有意思,括号是可以省略的,return可写可不写,请看示例:

task hello{ println'Hello World!' def a = compute(1, 2) println a def b = compute 3, 4 println b } def compute(int a, int b) { // return a + b; a + b; }

5.5 getter/setter

task hello{ Person person = new Person() person.name = '子云心' println person.name println person.age } class Person { private String name; // 私有变量也能被访问 public int getAge() { // 方法也可被直接当属性使用 25; } }

5.6 闭包(代码块)

一段被大括号包括的代码称为闭包或代码块。Groovy中是允许其作为参数传递的,像上面使用到的集合each方法为例,它接收的参数其实就是一个闭包:

// 呆板的写法 numList.each({ println it }) // 格式化后 numList.each( { println it }) // 如果方法的最后一个参数是闭包,可以放在方法外面 numList.each() { println it } // 方法是可以省备括号的 numList.each { println it }

来自定义一个闭包作参数传递的示例:

task hello{ customEach { println it } } def customEach(closure) { for(int i in i..10) { closure(i) } }

说明:

当定义的方法只接收一个参数,用于接收一个闭包时,那么就可以默认使用it变量

向闭包传递参数示例:

task hello{ customEach2{k, v -> println "${k} is ${v}" } } def customEach2(closure) { def mapSize = ["width":1920, "height":1080] mapSize.each { closure(it.key, it.value); } }

说明:

当闭包需要传递参数时,就不再使用it了,必须显式声明出来。

委托闭包

Groovy的闭包有thisObject、owner、delegate三个属性,当闭包内调用方法时,由它们来确定使用哪个对象来处理。示例:

task hello{ new Delegate().test { println "thisObject:${thisObject.getClass()}" println "owner:${owner.getClass()}" println "delegate:${delegate.getClass()}" methodl(); it.methodl(); } } def methodl() { println "Context this:${this.getClass()} in root" } class Delegate { def methodl() { println "Delegate this:${this.getClass()} in Delegate" } def test(Closure<Delegate> closure) { closure(this) } }

输出结果:

thisObject:class build_eglgh8qvzzqz0eqp07enfojra

owner:class build_eglgh8qvzzqz0eqp07enfojra$_run_closure1

delegate:class build_eglgh8qvzzqz0eqp07enfojra$_run_closure1

Context this:class build_eglgh8qvzzqz0eqp07enfojra in root

Delegate this:class Delegate in Delegate

说明:

thisObject的优先级最高,delegate和owner是相等的,但owner要比delegate优化级高。

delegate是可以被修改的,Gradle中的闭包很多功能都是通过修改delegate来实现的,详细使用在后面介绍

6 任务

6.1 创建

Gradle创建任务的方式有多种

第一种,任务名字+闭包配置的方式(我们在上面看到的方式)

task hello{ doLast{ println'Hello World!' } }

第二种,变量方式,task(String name)方法接收一个任务名作为参数,然后赋予变量

def Task taskHello = task(hello) taskHello.doLast{ println'Hello World!' }

6.2 分组和描述

任务是可以分组的和添加描述的,这样就是便于我们对任务进行归类整理,建议大家在创建任务时都要进行这两个属性的配置,以便于团队开发时别人能清楚知道该任务的分类和用途。示例:

def Task taskHello = task(hello) taskHello.group = BasePlugin.BUILD_GROUP taskHello.description = '我是hello任务' taskHello.doLast{ println'Hello World!' }

或者

def Task taskHello = task(hello, group:BasePlugin.BUILD_GROUP, description:'我是hello任务') taskHello.doLast{ println'Hello World!' }

6.3 <<操作符

“<<”操作符在Gradle的Task上是doLast方法的知标记形式,所以上述示例也可以写成:

def Task taskHello = task(hello, group:BasePlugin.BUILD_GROUP, description:'我是hello任务') taskHello <<{ println'Hello World!' }

6.4 任务顺序

通过shouldRunAfter和mustRunAfter两个方法可以控制一个任务应该或者一定在某个任务之后执行。

taskB. shouldRunAfter(taskA)          表示taskB应用在taskA执行之后执行,但这里是应该,所以有可能并不会按预设的执行

taskB. mustRunAfter (taskA)           表示taskB一定在taskA执行之后执行。

6.5 任务依赖

除了使用方法进行任务间改变执行顺序外,还可以使用任务依赖关系。示例:

task taskA << { println 'This is taskA' } task taskB(dependsOn: taskA) << { println 'This is taskB' } task taskC { dependsOn taskB // 多个可用逗号分隔 doLast { println 'This is taskC' } }

说明:

在创建taskB任务时,可通过dependsOn 指写其依赖的任务在taskC任务执行时,也可以通过另外的方式让其依赖taskB当执行命令:gradle –q taskC后,输出结果应该是:

This is taskA

This is taskB

This is taskC

 

 

转载请注明原文地址: https://www.6miu.com/read-5037764.html

最新回复(0)