基本语法
上面说到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_2021-08-01_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:
- 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 )
输出:
那这个有什么用呢,后面实践部分会讲到。
其他
Groovy还有一些技巧:
- 读取xml文件,比如读取manifest.xml文件信息
- 封装独立的工具类tools.gradle,比如获取Android版本名称,版本号,拷贝文件等IO操作
这些等用到的时候再说