Gradle解读

Posted by HaoChen Blog on September 12, 2016

Gradle解读

本文章参考于邓凡平 http://www.infoq.com/cn/articles/android-in-depth-gradle

首先了解什么是Gradle是什么?有什么用?

  1. Gradle是一个构建工具IDE
  2. 作用解决App开发中构建过程中的各种问题

概念一:

build是什么?

翻译过来是构建. 叫make也行.j9ushi根据输入的信息然后干一些事情,最后得到几个产出物(Artifact) make就是根据makefile文件中写的规则,执行对应的命令,然后得到的目标产物

首先常用的构建工具有ANT,然后进化到Maven,ANT和Maven两个工具其实还算方便,Maven([‘meɪv(ə)n])编译规则是使用XML来编写的,虽然XML通俗易懂,但是很难再xml中描述if(){}else{},所以导致Gradle的爆红出现

Gradle解决了这些痛点所以Gradle选择了Groovy([‘gruːvɪ])

概念二:

Groovy是什么?

Groovy基于java并拓展了java,Groovy说白了就是把写java程序变得像写脚本一样简单,写完就可以执行,Groovy内部会将其编译成javaclass然后启动虚拟机来执行

Gradle特点: DSL,Domain Specific language 领域相关语言
说白了就是某个行业的行话

到此:学习Gradle要学习下面两个基础知识:

  1. Groovy,他时基于java,所以我们仅介绍java之外的东西,了解Groovy语言是掌握的基础
  2. Gradle作为一个工具,他的行话和他为人处事的原则

Groovy中的数据类型我们就介绍两种和Java不太一样的:

  • 一个是Java中的基本数据类型。
  • 另外一个是Groovy中的容器类。
  • 最后一个非常重要的是闭包。

重点一: 基本数据类型

作为动态语言,Groovy世界中的所有事物都是对象。所以,int,boolean这些Java中的基本数据类型,在Groovy代码中其实对应的是它们的包装数据类型。比如int对应为Integer,boolean对应为Boolean

重点二:容器类

Groovy中的容器类很简单,就三种:

  • List:链表,其底层对应Java中的List接口,一般用ArrayList作为 真正的实现类。
  • Map:键-值表,其底层对应Java中的LinkedHashMap。
  • Range:范围,它其实是List的一种拓展

List类

变量定义:List变量由[]定义,比如

def aList = [5,'string',true] //List由[]定义,其元素可以是任何对象

变量存取:可以直接通过索引存取,而且不用担心索引越界。如果索引超过当前链表长度,List会自动
往该索引添加元素

assert aList[1] == 'string'
assert aList[5] == null //第6个元素为空
aList[100] = 100  //设置第101个元素的值为10
assert aList[100] == 100

那么,aList到现在为止有多少个元素呢?

println aList.size  ===>结果是101

Map类

容器变量定义

变量定义:Map变量由[:]定义,比如

def aMap = ['key1':'value1','key2':true] 

Map由[:]定义,注意其中的冒号。冒号左边是key,右边是Value。key必须是字符串,value可以是任何对象。另外,key可以用''或""包起来,也可以不用引号包起来。比如

def aNewMap = [key1:"value",key2:true] //其中的key1和key2默认被
处理成字符串"key1"和"key2"

不过Key要是不使用引号包起来的话,也会带来一定混淆,比如

def key1="wowo"
def aConfusedMap=[key1:"who am i?"]

aConfuseMap中的key1到底是"key1"还是变量key1的值“wowo”?显然,答案是字符串"key1"。如果要是"wowo"的话,则aConfusedMap的定义必须设置成:

def aConfusedMap=[(key1):"who am i?"]

Map中元素的存取更加方便,它支持多种方法:

println aMap.keyName    <==这种表达方法好像key就是aMap的一个成员变量一样
println aMap['keyName'] <==这种表达方法更传统一点
aMap.anotherkey = "i am map"  <==为map添加新元素

Range类:

Range是Groovy对List的一种拓展,变量定义和大体的使用方法如下:

def aRange = 1..5  <==Range类型的变量 由begin值+两个点+end值表示
                      左边这个aRange包含1,2,3,4,5这5个值

如果不想包含最后一个元素,则

def aRangeWithoutEnd = 1..<5  <==包含1,2,3,4这4个元素
println aRange.from
println aRange.to

重点:闭包Closure

def aClosure = {//闭包是一段代码,所以需要用花括号括起来..
Stringparam1, int param2 -> //这个箭头很关键。箭头前面是参数定义,箭头后面是代码
println”this is code” //这是代码,最后一句是返回值,
//也可以使用return,和Groovy中普通函数一样
}

闭包的格式

def xxx = {paramters -> code} //或者
def xxx = {无参数,纯code} 这种case不需要->符

使用:

闭包对象.call(参数) 或者更像函数指针调用的方法:

闭包对象(参数)

aClosure.call(“this is string”,100) 或者
aClosure(“this is string”, 100)

如果闭包没定义参数的话,则隐含有一个参数,这个参数名字叫it,和this的作用类似。it代表闭包的参数

比如:

def greeting = { "Hello, $it!" }
assert greeting('Patrick') == 'Hello, Patrick!'

等同于:

def greeting = { it -> "Hello, $it!" }
assert greeting('Patrick') == 'Hello, Patrick!'

但是,如果在闭包定义时,采用下面这种写法,则表示闭包没有参数!

def noParamClosure = { -> true }

这个时候,我们就不能给noParamClosure传参数了!

noParamClosure ("test")  <==报错喔!

Closure使用中的注意点

1. 省略圆括号

闭包在Groovy中大量使用,比如很多类都定义了一些函数,这些函数最后一个参数都是一个闭包。比如:

public static List each(List self, Closure closure) 上面这个函数表示针对List的每一个元素都会调用closure做一些处理。这里的closure,就有点回调函数的感觉。但是,在使用这个each函数的时候,我们传递一个怎样的Closure进去呢?比如:

def iamList = [1,2,3,4,5] //定义一个List iamList.each{ //调用它的each,这段代码的格式看不懂了吧?each是个函数,圆括号去哪了? println it }

等同于:iamList.each(Closure),但是在这里最后一个参数是一个闭包时是可以省略的

 doLast({
   println 'Hello world!'
})

doList{
	println 'Hello world'
} 一致 但是这里不表示走到doList就执行了 `println 'Hello world'`  而是表示doList()方法传入的参数为Closure,这个Closure正好是

{无参->println ‘hello world’ }

这段代码执没执行时要看 doList方法是否有没有调用 Closure的call 方法

方法:

public static <T> List<T> each(List<T> self, Closure closure) 使用

def iamList = [1,2,3,4,5]  //定义一个List变量
iamList.each{  //调用它的each函数,只要传入一个Closure就可以了。
  println it
}

不写参数时不是没有参数而是省略了参数it

对Map的findAll而言,Closure可以有两个参数。findAll会将Key和Value分别传进去。并且,Closure返回true,表示该元素是自己想要的。返回false表示该元素不是自己要找的。

def result =aMap.findAll{
key,value->println "key=$key,value=$value"
if(key=='k1')
return true
return false
}

println result

这里返回的是 [k1:value1] 表示是我们要找的

Closure的使用有点坑,很大程度上依赖于你对API的熟悉程度,所以最初阶段,SDK查询是少不了的。

脚本类:

Groovy把它转换成这样的Java类:

执行 groovyc -d classes test.groovy

groovyc 命令

Gradle的使用

查看当前文件目录下有那些task,如果cd进入到目录中去就不需要project-path

  • gradle project-path:tasks

http://blog.csdn.net/lzyzsd/article/details/46935063

Gradle for Android 第一篇( 从 Gradle 和 AS 开始 )

https://segmentfault.com/a/1190000004229002