第三章 Gradle构建脚本基础

简介: 从这章开始,会对Gradle有一个大概的介绍,帮助大家快速的入门Gradle。本章从整体构建脚本的角度介绍Gradle,什么是Settings文件,他有什么作用;什么是Build文件,它又有什么作用,我们可以新建多少Build文件。

从这章开始,会对Gradle有一个大概的介绍,帮助大家快速的入门Gradle。本章从整体构建脚本的角度介绍Gradle,什么是Settings文件,他有什么作用;什么是Build文件,它又有什么作用,我们可以新建多少Build文件。


然后会介绍Gradle的两个重要的概念:Project和Task,他们有什么作用,又有什么关系,如何创建一个Task,如何对Task进行配置,Task之间如何建立依赖关系;Task如何使用API控制和Task之间的通信等等。


最后介绍的是自定义属性,他们有何作用,如何定义,什么时候会用到等等,最后最后强调的是脚本就是代码,以写代码的方式来写脚本,灵活运用。


3.1 Setting文件


在Gradle中,定义了一个设置文件,用于初始化以及工程树的配置。设置文件的默认名字是settings.gradle,放在根工程目录下。


设置文件大多数的作用都是为了配置子工程。在Gradle多工程是通过工程树表示的,就相当于我们在Android Studio看到的Project和Module概念一样。根工程相当于Android Studio中的Project,一个根工程可以有很多子工程,也就是很多Module,这样就和Android Studio定义的Module概念对应上了。


3.2 Build文件


每个Project都会有一个build文件,该文件是该Project构建的入口,可以在这里针对该Project进行配置,比如配置版本,需要哪些插件,依赖哪些库等等。


既然每个Project都会有一个build文件,那么Root Project也不例外。Root Project可以获取到所有的Child Project,所以在Root Project的build文件里我们可以对Child Project统一配置,比如应用的插件,依赖的Maven中心库等等。这一点Gradle早就考虑到了,为我们提供了便捷的方法进行配置,比如配置所有Child Project的的仓库为jcenter,这样我们依赖的jar包就可以从jcenter中心库中下载了:


image.png


还比如我们在开发一个大型的Java工程,该工程被分为很多小模块,每个模块都是一个Child Project,这些模块同样夜都是Java工程,这种情况下我们也可以统一配置,应用Java插件:


image.png


这非常方便,省去了我们一个个Project去配置的情况,特别对于要管理很多的Project的大工程来说。除了提供的subprojects之外,还有allprojects,从其名字就可以看出来,是对所有Project的配置。


上面讲了很多配置,但是大家不要误以为subprojects和allprojects只能配置,他们只是两个方法,接受一个闭包作为参数,对工程进行遍历,遍历的过程中调用我们自定义的闭包,所以我们可以在闭包里配置,打印,输出,修改Project的属性都可以。


3.3 Projects以及tasks


其实一个Project就是在你的业务范围内,被你抽象出来的一个个独立的模块,你可以根据你的情况抽象归类,最后这一个个的Project组成了你的整个Gradle构建。


从我们编码的角度讲,他们就是一个个独立的模块,好好利用他们吧,这样你的代码就能够做到低耦合、高内聚啦。


一个Project又包含很多个Task,也就是说每个Project是由多个Task组成的。那么什么是Task呢?Task就是一个操作,一个原子性的操作,比如打个jar包,拷贝一份文件,编译一次Java代码,上传一个jar到Maven中心库等等,这就是一个Task,和Ant里的Target,Maven的goal是一样的。


3.4 创建一个任务


这里的task看着像一个关键字,其实他是Project对象的一个函数,原型为create(String name, Closure configureClosure)


task customTask1 {      
    doFirst{
        println 'do first'
    }
    doLast{
        println 'doLast'
    }
}
//我们还可以通过TaskContainer创建任务,Project对象已经默认定义好了TaskContainer,这就是tasks:
tasks.create('customTask2') {       
    doFirst{
        println 'do first2'
    }
    doLast{
        println 'doLast2'
    }
}


3.5 任务依赖


任务之间使可以有依赖关系的,这样我们就能控制哪些任务先于哪些任务执行,哪些任务执行后,其他任务才能执行。比如我们运行jar任务之前,compile任务一定要执行过,也就是jar依赖于compile;Android的install任务一定要一来package任务进行打包生成apk,然后才能install设备里。


task hello {        
    doLast{
        println 'hello'
    }
}
task world {        
    doLast{
        println 'world'
    }
}
task exTask(dependsOn: hello) {     
    doLast{
        println '---Task end---'
    }
}
task exMultiTask {  
    dependsOn hello, world  
    doLast{
        println '---MultiTask end---'
    }
}


dependsOn是Task类的一个方法,可以接受多个依赖的任务作为参数。


3.6 任务间通过API控制、交互


创建一个任务和我们定义一个变量是一样的,变量名就是我们定义的任务名,类型是Task(参见Gradle API Doc),所以我们可以通过任务名,使用Task的API访问它的方法,属性,或者对任务重新配置等,这对于我们操纵任务是非常方便和灵活的,Ant的Target就没有这个这个特性。


和变量一样,要使用任务名操纵任务,必须先定义声明,因为脚本是顺序执行的。

如上示例,我们调用了doLast和First方法,在任务执行前后做一些事情。对于直接通过任务名操纵任务的原理是:Project在创建该任务的时候,同时把该任务对应的任务名注册为Project的一个属性,类型是Task。我们稍微改动下例子,看看是否有ex36Hello这个属性:


image.png


我们通过println project.hasProperty('ex36Hello')检查是否有这么个属性,运行后通过输出我们可以看到,打印的是TRUE,说明每一个任务都是Project的一个属性。


既然可以通过API操纵任务,那么当创建了多个任务时,同样也可以通过API让他们相互访问,比如可以增加一些依赖等等,就像两个两个变量相互访问一样.


3.7 自定义属性


Project和Task都允许用户添加额外的自定义属性,要添加额外的属性,通过所属对应的ext属性即可,添加之后可以通过ext属性对自定义属性读取和设置,如果要同时添加多个自定义属性,可以通过ext代码块:

//自定义一个Project的属性
ext.age = 18
//通过代码块同时定义多个自定义属性
ext{
    phone = 13874768888
    address = 'xiang'
}
task customProperty {   
    ext.inner = 'innnnnner'                 
    doLast{
        println project.hasProperty('customProperty') //true
        println project.hasProperty('age') //true
        println project.hasProperty('inner')//返回fasle
        println "${age}"
        println "${phone}"
        println "${inner}"
    }
}


相比局部变量,自定义属性有更为广泛的作用域,你可以跨Project,跨Task访问这些自定义属性,只要你能访问这些属性所属的对象,那么这些属性都可以被访问到。

自定义属性不仅仅局限在Project和Task上,还可以应用在SourceSet,这样等于每种SourceSet又多了一个可供配置的属性,想想我们Android Studio开发的时候,是不是有main SourceSet,当你使用productFlavors定义多个渠道的时候,还会新增其他很多的SourceSet。


3.8 脚本即代码,代码也是脚本


虽然我们在一个gradle文件中写脚本,但是我们写的都是代码,这一点一定要记清楚,这样你才能时刻的使用Groovy、Java以及Gradle的任何语法和API帮你完成你想做的事情,不要被脚本这两个字给限制死,是脚本吗?是的没错,但是不是简单的脚本,在这脚本文件上你可以定义Class,内部类,导入包,定义方法,常量,接口,枚举等等,都是可以的,灵活运用,我们我们在项目中需要给生成的APK包以当前日期的格式命名,我们就定义了一个获取日期格式的方法,用于生成APK的文件名:


def buildTime(){
    def date = new Date()
    date.format('yyyy-MM-dd hh:ss')
}


这只是使用的一个例子,目的是让大家灵活搭配Java、Groovy和Gradle,不要把它当成简单的脚本,所以它是一个脚本文件。




本文属自学历程, 仅供参考


详情请支持原书 Android Gradle权威指南



目录
相关文章
|
7月前
|
存储 缓存 Java
《Gradle构建脚本的基本结构和语法》
《Gradle构建脚本的基本结构和语法》
88 0
|
17天前
|
XML 缓存 Java
Gradle 构建自动化工具入门
Gradle 构建自动化工具入门
|
2月前
|
Java 测试技术 API
云效流水线构建gradle项目失败提示gradle版本过低如何解决
云效(CloudEfficiency)是阿里云提供的一套软件研发效能平台,旨在通过工程效能、项目管理、质量保障等工具与服务,帮助企业提高软件研发的效率和质量。本合集是云效使用中可能遇到的一些常见问题及其答案的汇总。
43 0
|
7月前
|
缓存 Java Maven
深入理解Gradle构建系统的工作原理
深入理解Gradle构建系统的工作原理
174 0
|
9月前
|
设计模式 Java Android开发
基于Gradle的Spring源码下载及构建技巧
首先你的JDK需要升级到1.8以上版本。从Spring 3.0开始,Spring源码采用GitHub托管,不再提供官网下载链接。这里不做过多赘述,大家可自行去GitHub网站下载,我使用的版本下载链接为 https://github.com/spring-projects/spring-framework/archive/v5.0.2.RELEASE.zip ,下载完成后,解压源码包会看到如下图所示的文件目录。
168 0
|
12月前
|
编解码 前端开发 Java
Spring Boot-Spring Tool Suit + Gradle 构建第一个Spring Boot 项目02
Spring Boot-Spring Tool Suit + Gradle 构建第一个Spring Boot 项目02
67 0
|
12月前
|
IDE 前端开发 Java
Spring Boot-Spring Tool Suit + Gradle 构建第一个Spring Boot 项目01
Spring Boot-Spring Tool Suit + Gradle 构建第一个Spring Boot 项目01
74 0
|
Java API
Gradle学习基础(3):build脚本基础知识
Gradle学习基础(3):build脚本基础知识
Gradle学习基础(3):build脚本基础知识
|
Java Android开发
Gradle学习基础(2):构建简单的JAVA项目
Gradle学习基础(2):构建简单的JAVA项目