Gradle 权威指南--笔记

1.Gradle入门

Gradle是一个非常优秀的构建系统工具,它的DSL基于Groovy实现。

1.1 配置Gradle环境

grdle需要Java环境,要求JDK 6 以上,并且要配置Java的环境变量。

Gradle文件说明
官网下 https://gradle.org/ 载,得到压缩包 gradle-2.14.1-all.zip 。然后解压。得到目录清单

1.docs API DSL 指南文档
2.getting-started.html
3.init.d gradle初始化脚本目录
4.lib
5.LICENSE
6.media icon 资源
7.NOTICE
8.sample 示例
9.src 源文件

然后把GRADLE_HOME/bin添加环境变量路径里。
执行:
gradle -v 可以查看是否安装成功。
如果要在AS里执行,记得重启AS.

task hello{
    
    
	doLast{
    
    
		println "hello world"
	}
}

执行命令:gradle -q hello
-q 参数用于控制gradle输出的日志级别

1.2.Gradle Wrapper

是对gradle的包装,便于团队开发过程中统一Gradle构建的版本。这样大家可以使用统一的Gradle版本进行构建。wrapper在window下一个处理脚本,在linux下是一个shell脚本。他会检查Gradle有没有被下载关联。

  1. 生产wrapper
    gradle提供了内置的Wrapper Task帮助我们自动生成Wrapper所需的文件目录。在一个项目的根目录输入gradle wrapper即可生成。

gralde wrapper
distributionBase=GRADLE_USER_HOME 主目录
distributionPath=wrapper/dists 相对distributionBase的路径
zipStoreBase=GRADLE_USER_HOME 同distributionBase
zipStorePath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-6.5-bin.zip Gradle发行版压缩包的下载地址。

1.3.自定义Wrapper

gradle-wrapper.properties由wrapper task生产的。我们可以自定义wrapper task任务来达到配置gradle-wrapper.properties。

task wrapper(task:Wrapper){
    
    
	gradleVersion = '2.4'
}

distributionBase=GRADLE_USER_HOME
//下载gradle的路径
distributionUrl=https://services.gradle.org/distributions/gradle-6.7.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

1.4 gradle 日志

ERROR
QUIET
WARNING
LIFECYCLE 进度消息
INFO
DEBUG

输入Quiet级别之上的日志
gradle -q tasks

a 错误堆栈信息

默认情况下,堆栈信息是关闭的。需要我们通过命令行的堆栈信息开关打开它。
-s or --stacktrace 输出关键性信息
-S or --full-stacktrace 输出详细信息

b logger. 日志调试

logger.quiet("")
logger.error("")

1.5 gradle 命令行

./gradlew 是Mac的命令,如果你是window,输入gradle
使用帮助

./gradlew -?
./gradlew -h
./gradlew -help

强制刷新依赖

./gradlew --refresh-dependencies assemble

多任务调用
有时候我们要同时运行多个任务,比如执行jar之前,先clean

./gradlew clean jar

通过任务名字缩写执行
比如有个任务connectCheck
可以执行:

./gradlew cc

2.Groovy基础

Groovy是基于JVM的一种动态语言,Groovy完全兼容Java,有在此增加很多动态类型和灵活的特性。如 闭包 DSL

2.1 字符串

Groovy不需要分号,单引号和双引号都可以。
单引号没有运算能力,表示常量字符串。双引号可以直接运行表达式计算。

2.2 集合

Groovy完全兼容Java的集合,且进行了扩展。
list set map Queue

list
def numlist = [1,2,3,4] 使用索引访问集合
map
def map = ['width':1024,'height':768]
println map['width']

map.each{
    
    
	println "key:${it.key},Value:${it.value}"
}

2.3 方法

def method(int a,int b){
    
    
	println a+b
}
task invokeMethod<<{
    
    
	method(1,2)
}

return 可以不写

代码块是可以作为参数传递的

2.4 JavaBean

class Person{
    
    
	private String name
}

task hellJava <<{
    
    
	person p = new Person()
	p.name ="lisi"
	println "名字是:${p.name}"
}

2.5 闭包

闭包就是一段代码块

task helloClosure<<{
    
    
    customEach{
    
    
        print it
    }
}
//closure参数用于接收闭包(代码块)
def customEach(closure){
    
    
    for (i in 0..<10) {
    
    
        closure(i)
    }
}

传递参数

我们为闭包传递了两个参数,key .value


task helloClosure  {
    
    
    eachmap {
    
     K, V ->

        println "$K  $V"
    }
}

  def eachmap(closure) {
    
    
    def map = ["one": 1, "two": 2]
    map.each {
    
    
        closure(it.key, it.value)
    }
}

闭包委托

闭包的强大之处在于支持闭包方法的委托。Groovy的闭包有thisObject、owner、delegate三个属性。
当你在闭包内调用方法时,有它们来确定使用哪个对象来处理。默认delegate/owner是相等的。但是delegate可以被修改的。Gradle中的闭包的很多功能都是通过修改delegate实现的。

task helloDelegate  {
    
    

    new Delegate().test {
    
    
        println "thisObject:${thisObject.getClass()}"
        println "owner:${owner.getClass()}"
        println "delegate:${delegate.getClass()}"

        method1()
        it.method1()
    }
}
def method1() {
    
    
    println "context this:${this.getClass()} in root"
    println "method1 in root"
}
class Delegate {
    
    
    def method1() {
    
    
        println "Delete this:${this.getClass()} in Delegate"
        println "method1 in Delegate"
    }

    def test(Closure<Delegate> closure) {
    
    
        closure(this)
    }
}

result:

thisObject:class build_9eq7gfn6et0rl6qz17rvoqogw
owner:class build_9eq7gfn6et0rl6qz17rvoqogw$_run_closure2
delegate:class build_9eq7gfn6et0rl6qz17rvoqogw$_run_closure2
context this:class build_9eq7gfn6et0rl6qz17rvoqogw in root
method1 in root
Delete this:class Delegate in Delegate
method1 in Delegate

thisObject的优先级最高。默认情况下,优先使用thisObject来处理闭包中调用的方法,如果有则执行。thisObject其实就是这个构建脚本的上下文,它和脚本中的this对象是相等的。

列子中也证明delegate和owner是相等的,两个的优先级是:owner比delefate高。所以闭包内方法的处理顺序是:thisObject>owner>delegate。

2.6 DSL 领域特定语言

DSL (domain specific Language)领域特定语言。专注某个领域的语言。Gradle就是一个DSL.基于Groovy,专门解决自动化构建的DSL.

3.Gradle构建基础

3.1 setting文件

用于初始化及工程树配置。为了配置子工程。
子工程只有在settting文件里配置了才能识别、

3.2 build.gradle文件

每个project都会有一个build.gradle文件,它是project构建入口,配置版本,依赖库,配置插件。
Root Project也可以获取所有child project,比如Java在开发大型项目的时候,会有很多模块,每个模块都是project。

subprojects {
    
    
	apply plugin "java"
    repositories {
    
    
       		jecenter()
       }
    }
}

3.3 projects 及Tasks

gradle中,可以有很多project,可以定义project生成jar,生成war包,也可以创建project用于上传war文件。一个project又包含多个task。
task是一个操作,一个原子性操作。比如打个jar包,复制一分文件,编译一次Java代码

task xxxx{
    
    
    doOne{
    
    
        println 'hello'
    }
     
}

3.4 创建一个任务

task customTask1{
    doFirst{
        println "this is task"
    }
    doLast{
    	println "this is last"
    }
}

task是一个关键字,它是project对象的一个函数,原型为create(String name,Closure configureClosure),customTask1是任务的名字;第二个参数是闭包,大括号里的代码。

tasks.create("customTask2"){
    
    
    doFirst {
    
    
        println "one"
    }
    doLast {
    
    
        println "two"
    }
}

3.5 任务依赖

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

task hello  {
    
    
    println "hello"
}
task exMain (dependsOn:hello){
    
    
    doLast {
    
    
        println "main"
    }
}

还可以依赖多个task

task exMain (){
    
    
    dependsOn hello,world
    doLast {
    
    
        println "main"
    }
}

3.7 自定义属性

project和Task 都可以让用户添加额外的自定义属性,使用ext

ext.name = 'lisi'
ext{
    
    
    phone =890
    address = 'hello'
}
task one{
    
     
    println "$name"
    println "$phone"
    
}

自定义属性还可以使用在sourceSet中,


sourceSets.all{
    
    
    ext.resourceDir = null
}

sourceSets{
    
    
    
    main{
    
    
        resourcesDir ='/main'        
    }
    
    test{
    
    
        resourcesDir ="/test"
    }
}

4.Gradle 任务

1.多种方式创建任务

依赖于project给我们提供的快捷方法及TaskContainner提供的相关Create方法,可以有多种方式来创建任务。


def Task createTask = task(createTask)

createTask.doLast {
    
    

    println "hello world"
}

createTask就是任务名字,可以使用.gradlew createTask 来执行这个任务。这种方式的创建其实调用project对象中的task(String name)的方法
第二种方式 以一个任务名字+ 一个对该任务配置的map对象来创建任务。

def Task createTask2 = task(createTask2,group: BasePlugin.BUILD_GROUP)

第三种:任务+闭包

task createTask3{
    
    
    decription "演示"
    doLast {
    
    
        println "this is task + closure style"
    }
}

2.多种方式访问任务

我们创建的任务都会作为项目(project)的一个属性,属性名就是任务名,可以直接通过该任务名字访问和操作该任务;

其次,任务都是通过TaskContainer创建的,它是我们创建任务的集合,在project中我们通过tasks属性访问TaskContainer.访问的时候,任务名就是key

再则,通过路径访问,一个是get 一个是find,区别为get的时候如果找不到会抛出异常UnknowTaskException。而find找不到返回null。

通过名称访问,也有get 和find 两种,区别和上述一样。

3.任务分组和描述

任务分组就是分类,便于对任务进行归类整理。任务的描述就是说明这个任务有什么作用。

4.<< 操作符

<< 操作符在gradle的task是doLast的短标记形式。

5.任务的执行分析

当我们执行一个Task的时候,其实就是执行其拥有的actions列表,这个列表保存在Task对象实例中的actions成员变量中,其类型是一个List

List<ContextAwareTaskAction> actions = new ArrayList<>()

我们把task之前执行、task本身执行、task之后执行分别称为doFirst 、doSelf、doLast

Task task = task two(type: CustomTask)

task.doFirst {
    
    
    println '之前执行'
}
task.doLast {
    
    
    println '之后执行'
}

class CustomTask extends DefaultTask {
    
    
    @TaskAction
    def doSelf() {
    
    
        println 'task 自身执行'
    }
}

6.任务排序

通过shouldRunAfter和mustRunAfter这两个方法,可以控制一个任务应该或者一定在某个任务之后执行,你可以控制任务的执行顺序,而不是通过强依赖的方式。

taskB.shouldRunAfter(taskA) 表示taskB 应该在taskA执行之后执行,这里的应该不是必须,有可能任务顺序不能按照预期完成。而mustRunAfter(taskA) 表示严格执行。

7.任务的启用和禁用

Task中有个enable属性,用于启用和禁用任务。默认true,表示启用。

8.任务的OnlyIf断言

断言就是一个条件表达式,Task有一个onlyif方法,接受一个闭包作为参数。如果该闭包返回ture表示任务执行。否则跳过。

9.任务规则

我们创建的任务都有TaskContainer进行管理,所以当我们访问任务的时候都是通过TaskContainner进行访问,而TaskContainner继承NamedDomainObjectCollection,所以任务规则其实就是NamedDomainObjectCollection的规则

5.Gradle 插件

6.java Gradle插件

7.Android Gradle插件

8.自定义Android Gradle工程

猜你喜欢

转载自blog.csdn.net/chentaishan/article/details/120168896
今日推荐