安装Gradle
- 确保安装你的电脑了Java7或以上版本
- 在这里下载最新的Gradle distribution
- 创建一个文件夹,把下载的压缩包解压进去(以
C:\Gradle
为例),然后进入文件夹中的bin目录,复制路径(C:\Gradle\gradle-4.3.1\bin
),把路径加入到系统环境变量的Path
中 - 命令行输入
gradle -v
,显示Gradle版本即安装完成
注:官方指南
Groovy基础知识
Groovy简介
Groovy是一种基于JVM的敏捷开发语言,他可以和Java进行混写,同时Groovy在配置信息上又比Java要灵活,他具有闭包和动态语言中的其他特性。
正题
在Groovy中,你可以这样打印一句话,跟Java很像有木有
println "Hello Groovy!"
Groovy与Java混写,这样是没问题的
//Java
class JavaGreeter {
public void sayHello() {
System.out.println("Hello Java!");
}
}
//Groovy
def greeter = new JavaGreeter()
greeter.sayHello()
Groovy只在运行时检查类型,也就是说我们不需要申明变量的类型,并且可以中途改变类型
def foo = 6.5//这里foo是一个浮点数
foo = "a string"//这里foo变为一个字符串
Groovy中字符串的拼接和Kotlin中的很像
println "foo has value: $foo"//$后加变量名
println "Let's do some math. 5 + 6 = ${5 + 6}"//${表达式}
Groovy的函数不需要申明参数类型,也不需要写return,写在函数里的最后一个表达式就是返回值
def doubleIt(n) {
n + n
// return n + n 也可以
}
Groovy中的函数调用有点意思,无参函数的调用必须加括号,有参函数调用可以不加括号,参数之间用逗号隔开
def noArgs() {
println "Called the no args function"
}
def oneArg(x) {
println "Called the 1 arg function with $x"
x
}
def twoArgs(x, y) {
println "Called the 2 arg function with $x and $y"
x + y
}
oneArg 500 //ok,没问题
twoArgs 200, 300//ok,也没问题
noArgs //。。。有问题
noArgs() //没问题
twoArgs oneArg 500, 200 // 这样的嵌套是有问题的,groovy不能识别你的参数到底是给谁的
twoArgs oneArg(500), 200 // 这样就很确定了,500是给oneArg,返回值和200给twoArgs
Groovy的闭包,感觉和Kotlin的λ表达式基本相同,可以作为一个变量,闭包的调用和函数是一样的
def noArgs = {
println "Hello from a closure"
println "The value of foo is $foo"
}//不接受参数的闭包
def oneArg = { x -> x + x}//接受一个参数的闭包
noArgs()
twoArgs 200, 300
Groovy的闭包可以通过委托(delegate)来把自己变成一个类的函数
//定义一个类
class A {
String b = "123"
def c(){println "321"}
}
//生成该类对象
def myA = new A()
//定义一个闭包,在里面操作A类中的变量和函数
def d = {
b = "1234"
c()
}
//这样调用是报错的,他不知道去哪里找到b和c()
d()
//把A类的实例赋值给闭包的委托,这样闭包就可以操作A类的东西了
d.delegate = myA
d() // ok
在Groovy中用闭包来遍历列表什么的很方便,和kotlin一样
//定义一个列表
def myList = ["Gradle", "Groovy", "Android"]
//定义一个接受一个参数的闭包
def printItem = {item -> println "List item: $item"}
//List的each函数接收一个参数的闭包,这样就把所有item打印出来了
myList.each(printItem)
/*
当然如果韩式嫌麻烦的话可以省去定义闭包的部分
这种方式下,如果函数接受的闭包是只有一个参数的,那么他默认为it
*/
myList.each{println "List item: $it"}
Gradle Now
怎么运行Gradle代码
- 首先要有一个编写Gradle的地方,只要能打字,什么卵都是可以的,我建议使用Sublime
- 然后创建一个
build.gradle
文件,在里面写代码,保存 - 命令行或者powerShell到当前目录下,输入gradle的命令就ok,比如要看看
build.gradle
里面有什么task就输入gradle tasks
,要执行里面的task就输入gradle [taskName]
Task
task就是一个个的任务,可以单独的执行,如下声明一个task
task("myTask1")//ok
task "myTask2"//ok
task myTask3//ok
//给任务加上描述
myTask3.description = "This is what's shown in the task list"
//给任务分组
myTask3.group = "Some group"
//任务最后会执行的闭包
myTask3.doLast {println "Do this last"}
//任务一开始就执行的闭包
myTask3.doFirst {println "Do this first"}
/*
把这些配置放到闭包configureClosure中也是ok的
*/
task myTask4 {
description "Here's a task with a configuration block"
group "Some group"
doLast {
println "Here's the action"
}
}
这样也是可以的,括号里接受一个Map来描述一些配置信息
task myTask5(description: "Another description") {
doLast {
println "Doing something"
}
}
能以Map的方式写在括号里的配置还有这些
命令行输入gradle tasks
看看,本来是会显示很多东西的,但是这里只把和上面代码有关的贴出来
上面明明写了好多个task,但是他只显示了Some group分组下的两个task,其他不见了,仔细看他说To see all tasks and more detail, run gradle tasks --all
,试试吧
好的我们定义的task全都出来了,有分组的都在同一分组下,没分组的在Other tasks
下,并且有描述的都可以看见描述。现在这些task都是可以执行的,试试gradle myTask3
,输出如下
Task :myTask3
Do this first
Do this last
Task Dependencies
dependsOn
以下面的代码为例,表示b依赖于a
执行b的结果:
a
b
执行a的结果:
a
task a {
doLast {
println "a"
}
}
task b {
dependsOn "a"
doLast {
println "b"
}
}
finalizedBy
以下面的代码为例,表示a要以b结尾
执行a的结果是:
a
b
执行b的结果是:
b
task a {
finalizedBy "b"
doLast{
println "a"
}
}
task b {
doLast {
println "b"
}
}
shouldRunAfter
以下面的代码为例,表示如果a和b都要执行,那么b应该在a的后面执行
执行a的结果是:
a
执行b的结果是:
b
a和b一起执行的结果是:
注:多个任务执行命令如右 gradle b a
a
b
task a {
doLast {
println "a"
}
}
task b {
shouldRunAfter "a"
doLast{
println "b"
}
}
mustRunAfter
个人觉得mustRunAfter和shouldRunAfter的效果是一样的
执行a的结果是:
a
执行b的结果是:
b
a和b一起执行的结果是:
a
b
task a {
doLast {
println "a"
}
}
task b {
mustRunAfter "a"
doLast{
println "b"
}
}
TaskType
如果实现每一个功能都要从零开始写就太麻烦了,Gradle已经为我们准备好了许多有用的Task,在这个网址左边的导航栏可以找到,下面介绍怎么使用这些TaskType,以复制文件为例Copy
,官网上的例子
//在括号里写上要使用的TaskType
task copyDocs(type: Copy) {
//从这个路径
from 'src/main/doc'
//到这个路径
into 'build/target/doc'
}
上面就是简单的使用了Copy这个TaskType来复制文件,还有很多高级玩法,不知道怎么玩的话就看看对应TaskType的文档说明,比如Copy
自定义TaskType
原来的TaskType不够玩了?那就扩展呗,其实就是写一个继承DefaultTask
的类,下面做最简单的示例
执行gradle hello
Me
class MyTask extends DefaultTask {
//类里面随便写
String who
/*
@TaskAction表示这个Task被执行的时候会做的事
*/
@TaskAction
void doAction() {
println "Hello $who"
}
}
task hello(type:MyTask){
who 'Me' //给who属性赋值
}
IncrementalBuilds
gradle有个棒棒的地方,就是他会智能的进行构造,假设就是简单的把某个文件Copy到某个地方,你运行这个task,文件复制好了,你再运行一次,她不会再去执行一次复制操作,只要你的输入输出没变,那么他就不会重复的执行,这在构造项目的时候就很有用了,也许你只改了一个字母,那他就不需要把所有文件都重新走一遍。
参数化构建
假设有下面这样一个Task,执行是肯定会报错的,找不到yourName
task hello{
println "hello $yourName"
}
向task传递yourName参数有三种方式,优先级依次递增
-
同目录下
gradle.properties
文件中声明yourName = 'chengge'
-
命令行输入
gradle -PyourName='weige' hello
build.gradle
中申明
ext {
yourName = "jige"
}
如果上面三种方法一起用上,那么效果是
jige
好了好了,水了一天,先到这里了,很多不充分的地方大家提出来呀,不对的地方大家指正呀!