Gradle学习(十一)——构建脚本基础知识

原创 2018年01月03日 16:26:22

转载请注明出处:http://blog.csdn.net/lastsweetop/article/details/78962619

项目和任务

Gradle的所有都是基于两个基础概念:项目和任务

每个Gradle构建是由一个或者多个项目构成的,项目表示什么取决于你用Gradle做什么。比如,项目可以表示jar库或者web程序。它也可以表示由其他项目生产的jar包后打包成的发布zip包。一个项目不一定非要表示构建什么。它也可以表示做什么,比如把你的app发布到脚手架或者生产环境。讲到这里,你可能有点迷糊,但是不要担心,Gradle对按惯例构建的支持给出了项目是什么更明确的定义。

每个项目是由一个和多个任务构成的。任务表示构建运行的工作原件。它可以是编译classes,创建jar,生成javadoc,也可以是发布archives到仓库中。

我们本章内容都是同一个项目下的一些简单的任务操作,多项目交互的要到后面的章节体现。

Hello World

运行gradle命令时,Gralde回去查找当前目录下的build.gradle文件,这个文件就可以叫做构建脚本,虽然看起来更像是构建配置脚本。构建脚本中定义了一个项目和项目的一些任务。

build.gradle的内容如下:

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

然后在当前目录执行gradle -q hello命令,结果如下:

± % gradle -q hello                                                       
Hello World

让我们来看看发生了什么,首先构建脚本定义了一个叫hello的任务,并且添加了一个action。当你运行gradle -q hello的时候,Gradle就会执行hello任务,然后执行你提供的action。这个action只是一个包含了简单的groovy代码的closure。

构建脚本即code

构建脚本其实就是groovy代码,通过强力的脚本语言groovy让构建脚本更加强力,例如:

task upper {
    doLast {
        def str = 'sWeeTop'
        println 'Original:' + str
        println 'Upper Case:'+str.toUpperCase()
    }
}

然后执行upper任务:

± % gradle -q upper                                                       
Original:sWeeTop
Upper Case:SWEETOP

再来一个:

task count {
    doLast {
        4.times { println it}
    }
}

然后执行count任务:

± % gradle -q count                                                       
0
1
2
3

任务依赖

我们在命令行那张也涉及了一点任务依赖的例子,我们现在再来讲解一下,例子如下:

task hello {
    doLast {
        println 'Hello World'
    }
}
task intro(dependsOn:hello) {
    doLast {
        println "I'm Gradle"
    }
}

然后执行intro任务:

± % gradle intro -q                                                       
Hello World
I'm Gradle

所依赖的任务还可以是预先未定义的,例子如下:

task taskX(dependsOn: 'taskY') {
    doLast {
        println 'taskX'
    }
}

task taskY() {
    doLast {
        println 'taskY'
    }
}

然后执行taskX任务:

± % gradle taskX -q                                                       
taskY
taskX

依赖于taskY的任务taskX却比taskY先定义,这个特性对多任务构建来说很重要。

还有一点要注意就是,采取惰性依赖你就无法使用所依赖任务的快捷符号了

动态任务

强力的Groovy各种66666,比如你可以定义动态的任务:

4.times { number ->
    task "task$number" {
        doLast {
            println "I'm task number $number"
        }
    }
}

然后执行task2任务:

± % gradle task2 -q                                                       
I'm task number 2

操作已存在的任务

一旦任务被创建之后,你就可以通过api直接访问了,比如你可以动态的给一个任务增加点依赖,ant可以做不到这点,示例:

4.times { number ->
    task "task$number" {
        doLast {
            println "I'm task number $number"
        }
    }
}

task0.dependsOn task2,task3

然后我们只想task0任务:

± % gradle task0 -q                                                       
I'm task number 2
I'm task number 3
I'm task number 0

或者为已经存在的任务增加点行为:

task hello {
    doLast {
        println 'Hello World'
    }
}
hello.doFirst {
    println 'Hello Dong'
}
hello.doLast {
    println 'Hello Nan'
}
hello {
    doLast {
        println 'Hello Bei'
    }
}

然后执行hello任务:

± % gradle hello -q                                                       
Hello Dong
Hello World
Hello Nan
Hello Bei

doFirstdoLast能被多次执行,他们可以在任务的开始和结尾增加action,任务执行的时候,action列表就会依次执行。

快捷符号

有个非常方便的符号可以访问已存在的任务,在构建脚本中的每个任务都有这些属性:

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

hello.doLast {
    println "Greeting from the $hello.name task"
}

然后执行hello任务:

± % gradle hello -q                                                      
Hello World
Greeting from the hello task

这样可以写出更加易读性的代码,特别是用那些插件提供的任务,比如compile任务

扩展任务属性

你可以为任务增加自己的属性,要增加myProperty属性你给ext.myProperty设置一个初始值,然后这个属性就和其他预先定义的属性一样被读取和设置。示例:

task myTask {
    ext.myProperty='init value'
}

task printTaskProperty {
    doLast {
        println myTask.myProperty
    }
}

然后执行printTaskProperty任务

± % gradle printTaskProperty -q                                           
init value

使用ant任务

ant任务是gradle的一等公民,gradle把通过把ant任务完全交托给groovy实现了卓越的集成。在groovy这里是由奇妙的AntBuilder提供相关功能。在Gradle里使用ant任务就像直接在build.xml里的任务一样简单而又强力。下面的例子演示了如何执行ant任务和访问ant属性:

task loadFile {
    doLast {
        def files = file('../unpublished').listFiles().sort()
        files.each { File file ->
            if (file.isFile()) {
                ant.loadfile(srcFile: file,property:file.name)
                println "  ***$file.name***  "
                println ant.properties[file.name]
            }
        }
    }
}

然后执行loadFile任务:

± % gradle loadFile -q                                                    
  ***build.gradle***  
apply plugin: 'java'

archivesBaseName='hello'
  ***settings.gradle***  
version = 1.0

使用方法

gralde在组织构建逻辑时可以进行分级扩展,组织构架逻辑的第一级就是提取方法:

task loadFile {
    doLast {
        fileListEachAction('../unpublished') { File file ->
            ant.loadfile(srcFile: file, property: file.name)
            println "  ***$file.name***  "
            println ant.properties[file.name]
        }
    }
}

task checkSum {
    doLast {
        fileListEachAction('../unpublished') { File file ->
            ant.checksum(file: file, property: "cs_$file.name")
            println "$file.name checksum is ${ant.properties["cs_$file.name"]}"
        }
    }
}

def fileListEachAction(String path, Closure closure) {
    def files = file(path).listFiles().sort()
    files.each { File file ->
        if (file.isFile()) {
            closure(file)
        }
    }
}

然后执行checkSum任务:

± % gradle checkSum -q                                                    
build.gradle checksum is 193e5061bf3681c0434d6f4d937f1fc3
settings.gradle checksum is 0cba3f2c2582e03de4dc86f1d495a39b

后面还会讲到,这样的方法在多项目构建中也可以跨项目调用。

默认任务

Gradle可以定义一个或者多个默认任务,当没有特别指定具体任务时,默认任务就会执行

defaultTasks 'clean','run'

task clean {
    doLast {
        println "task $it is running"
    }
}

task run {
    doLast {
        println "task $it is runing"
    }
}

执行默认任务:

± % gradle -q                                                             
task task ':clean' is running
task task ':run' is runing

相当于运行了gralde -q clean run,在多项目构建中,每个子项目都可以设置自己的默认任务,当没有子项目的默认任务被指定那么就会执行root项目的默认任务

通过DAG配置Gradle

Gradle有配置阶段和运行阶段,在配置阶段之后,Gradle就会知道所以需要执行的任务,Gradle提供了hook可以让你使用这些信息,有一个用例就是你需要确认release任务是否在执行的任务之中,在这个基础上你可以设置不同的变量。

下面的例子会演示contribution任务和release任务下会有不同的version值:

task distribution {
    doLast {
        println "Current Version is $version"
    }
}

task release(dependsOn: distribution) {
    doLast {
        println 'We release now'
    }
}

gradle.taskGraph.whenReady { taskGraph ->
    if (taskGraph.hasTask(release)) {
        version = '1.0.0'
    } else {
        version = '1.0.0-SNAPSHOT'
    }
}

执行distribution任务:

± % gradle distribution -q                                                
Current Version is 1.0.0-SNAPSHOT

执行release任务:

± % gradle release -q                                                     
Current Version is 1.0.0
We release now

最重要的是whenReady会影响release任务是在release任务执行之前,即使release任务不是该次构建的主要任务。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lastsweetop/article/details/78962619

终极版C语言(十一)

-
  • 1970年01月01日 08:00

Gradle构建脚本基础

Gradle构建脚本,内部是基于 Groovy 的 DSL(领域特点语言),而Maven是基于XML的,Groovy相比XML更加简洁、灵活和强大。 Groovy 因为给 Java 开发人员提供了最大...
  • zxc123e
  • zxc123e
  • 2017-06-01 13:54:47
  • 352

Gradle:构建脚本概要

一、构建块 1.每个构建块都包含三个基本构建块:project、task和property; 2.每个构建块包含至少一个project,进而又包含一个或多个task; 3.project和tas...
  • p106786860
  • p106786860
  • 2016-01-05 23:56:31
  • 2373

android gradle自动构建大总结

android gradle自动构建背景:日常出版本和线上出版本时,需要手动修改一些配置,包括key配置、线上/测试环境配置、版本号增加等,过程繁琐。所以对构建脚本进行改进,达到自动构建目的。...
  • duantihi
  • duantihi
  • 2017-02-16 13:25:18
  • 1999

Android面试系列文章2018之实战经验部分之gradle篇

Android面试系列文章2018之实战经验部分之gradle篇 Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语...
  • ClAndEllen
  • ClAndEllen
  • 2018-02-25 16:24:29
  • 232

Gradle Build Language Reference【Gradle构建语言参考文档】

Gradle配置文档
  • itzhengjun1987
  • itzhengjun1987
  • 2017-08-20 11:56:18
  • 130

手动迁移ADT 的ANT结构工程至Gradle

转载地址:http://www.jcodecraeer.com/a/anzhuokaifa/Android_Studio/2015/0127/2368.html 相关的gradle的文章:http:/...
  • lijinhua7602
  • lijinhua7602
  • 2015-04-15 14:44:17
  • 802

gradle eclipse下构建ssh2项目

这次构建主要遇到的问题: 1. 依赖脚本编写问题,对顶层包来说,有的被‘依赖’包是可选的,如果项目中要用到被依赖包,要显视配置进来,因为gradle依赖管理里面可选包不会被下载。我遇到的是sprin...
  • yangbo2921946188
  • yangbo2921946188
  • 2015-11-19 22:29:52
  • 1126

gradle学习笔记(一) 构建工具介绍

在android开发中平常所接触的gradle脚本,配置好了点击run按钮就能编译、打包、安装等等操作,编译出想要的apk,大大方便了开发过程。但是自己对gradle的了解和掌握仅仅只是够用,于是大量...
  • u014099894
  • u014099894
  • 2016-04-06 23:36:27
  • 794
收藏助手
不良信息举报
您举报文章:Gradle学习(十一)——构建脚本基础知识
举报原因:
原因补充:

(最多只允许输入30个字)