Gradle系列(一):Groovy基础
Gradle系列(一):Groovy基础
Gradle系列(二):AndroidStudio的Gradle简介
Gradle系列(三):项目实践
前言
关于Gradle的文章很多,但是大多是以一些技巧为主,东敲西打看了之后可能解决了一些问题,但对于新的需求,gradle如何运用到项目中还是一知半解。我准备稍微深层一点了解gradle,从基本语法开始到如何用到实际项目中,在此我把gradle的学习分成三个部分,分享给大家:
- 第一部分:Groovy基础
- 第二部分:android studio中gradle插件简介
- 第三部分:项目实践
Groovy基础
项目中build.gradle都是用groovy写的,不了解一下groovy怎么能看得懂呢?这里只需要知道groovy的一些基础知识,比如怎么定义变量,定义方法,方法怎么使用,闭包的使用,这些就差不多了。
首先要知道groovy是一种脚本语言,有下面三个特点:
- 是一种动态语言,不需要编译直接生效
- 是一种DSL,即Domain Specific Language(专门领域的编程语言,所以比较难阅读)
- Groovy基于Java同时也像是一种脚本语言(基于java,这个看下面基本语法就明白了)
基本语法
- ****定义基本变量:****
def variable1 = 1 //可以不使用分号结尾
def varable2 = "I am a person"
def int x = 1 //变量定义时,也可以直接指定类型
- ****字符串:****
1 单引号''中的内容严格对应Java中的String,不对$符号进行转义
def singleQuote='I am $ dolloar' //输出就是I am $ dolloar
2 双引号""的内容则和脚本语言的处理有点像,如果字符中有$号的话,则它会$表达式先求值。
def doubleQuoteWithoutDollar = "I am one dollar" //输出 I am one dollar
def x = 1
def doubleQuoteWithDollar = "I am $x dolloar" //输出I am 1 dolloar
3 三个引号'''xxx'''中的字符串支持随意换行 比如
def multieLines = ''' begin
line 1
line 2
end '''
- ****定义函数:****
String testFunction(arg1,arg2){//无需指定参数类型
...
}
def nonReturnTypeFunc(){
last_line //最后一行代码的执行结果就是本函数的返回值
}
//如果指定了函数返回类型,则可不必加def关键字来定义函数
String getString(){
return "I am a string"
}
- ****函数调用:****
println("test") ---> println "test"// 可以不加括号,但是建议:自定义的方法调用加上括号! API提供的方法调用可以不用括号
-
****数据类型:****
-
** java中的基础数据类型**
在Groovy中所有事物都是对象,int count = 12; //这里的count其实是Integer类型,其他的使用和Java一样
- ****容器类****
1.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
2.Map
Map由[:]定义,注意其中的冒号。冒号左边是key,右边是Value。key必须是字符串,value可以是任何对象。另外,key可以用''或""包起来,也可以不用引号包起来。比如
def mapData = [:]
mapData.put("name","test name")
println(mapData.get("name"))//输出“test name”
3.闭包(Closure)
- 定义:闭包,是一种数据类型,它代表了一段可执行的代码。他可以作为方法的参数,或者返回值,也可以独立运行
//自定义一个闭包
def aClosure = { //闭包是一段代码,所以需要用花括号括起来..
String param -> println("test closure,para = $param") //这个箭头很关键。箭头前面是参数定义,箭头后面是代码
return 200 //返回值
}
//调用这个闭包:(用call方法或者直接蚕食写在括号里面)
def count = aClosure.call("dml")
// def count2 = aClosure("dml")
println("$count")
在Gradle控制台看一下输出:
Paste_Image.png上面说到Closure也可以作为方法的参数,在Android Gradle中有不少这样的用法,比如:
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
// 输出apk名称为boohee_v1.0_2015-01-15_wandoujia.apk
def fileName = "boohee_v${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
}
分析一下这里代码是什么意思:
这里debug的配置代码:
作用是根据多渠道打包配置,重新命名APK(这里的实例代码是在productFlavors中配置了“wandoujia”),这里不考虑这个配置,看下这段代码用到了
applicationVariants.all和variant.outputs.each两个Android Gradle插件API提供了两个方法,第一个方法大致意思是获取project对应的app,第二个方法大致意思是遍历生成的所有debug和release的apk,并且重命名!
看下each这个方法,参数就是一个Closure,并且遍历自己,把每一个item传入这个自定义的Closure执行,而在这个Closure中就是我们自己的实现:传入
output变量,对output重命名。Closure有点类似java的函数回调。
- 闭包使用注意:
1.如果一个方法的最后一个参数是Closure那么,可以不用圆括号,比如上面的all方法和each方法
2.如果闭包没有定义参数,那么它默认拥有参数it,类似于java的this:
def bClosure = {println("param = $it")
}
bClosure.call("this closure!") //输出: param = this closure!
3.闭包的参数怎么传
比如上面的
variant.outputs.each方法,虽然知道他要传入closure参数,但是这个closure参数传几个呢 ? 我们无法确定,只有通过API:
才能知道这个closure只接受一个参数!如果我们传入多参数的closure这里会报错,所以说closure和上下文有很强的关联性,我们必须熟悉一些api才能很好地传入closure!
-
IO操作
Groovy提供了简单的读取文件的方法,通过一个实例了解一下:
在我们公司项目中,一些基础功能比如网络模块,通用控件等单独编译成aar文件,放到项目的根目录lib文件夹。
我们可以利用gradle的IO操作读取lib里面的file名称:
//获取基础库版本号
def path = rootProject.getRootDir().getAbsolutePath() + "/libs"
def configFile = new File(path)
def files = configFile.listFiles()
def aar1 = files[0].getName()
def aar2 = files[1].getName()
println(aar1 )
println(aar2 )
输出:
Paste_Image.png那这个有什么用呢,后面第三部分的实践会讲到。
其他
Groovy还有一些技巧:
- 读取xml文件,比如读取manifest.xml文件信息
- 封装独立的工具类tools.gradle,比如获取Android版本名称,版本号,拷贝文件等IO操作
这些等用到的时候再说