Android构建02-Groovy基础

前言


Groovy是JVM语言,与Java语法类似,如果你熟悉kotlin的话,你会发现它与kotlin更类似些。它可以作为Java平台的脚本语言使用。详细介绍请见Groovy官网维基百科

提示:“Groovy基础”这一部分建议不要花费太多时间,能看懂语法,尤其是闭包的语法,以及知道如何查阅API即可。


语法


对于语法的学习,我这里就不详细说了,请大家按照下面步骤去学习:

  1. 浏览一遍官方文档的语言规范,里面有示例,很容易看懂。要知道Groovy语言规范大致讲了哪些内容,以后遇到不懂的语法,可以回来快速查阅。
  2. 另外,也可以看下国人写的入门博客:任玉刚 Gradle从入门到实战 - Groovy基础使用Groovy开发之新特性

重点看的部分

  1. 闭包Closures。定义、使用、代理策略(owner, delegate and this)
  2. 语义Semantics。重点看Promotion and coercionOptionalityTyping部分,尤其是和闭包相关的部分。


API文档使用说明


Groovy API包括两部分,一部分是Groovy化的JDK API(groovy-jdk),另一部分是新增的纯Groovy API(gapi)。

文档入口:

  1. 官网Document->API documentation
    Groovy API入口
  1. 直接进入API文档
    Groovy Api Document
Groovy化的JDK API

This document describes the methods added to the JDK to make it more groovy.

Groovy在JDK中增加了许多方法,如在List增加了public List each(Closure closure)public List dropWhile(Closure condition)等方法,使其Groovy化。

查找API示例:查看Listpublic List each(Closure closure)方法详情。

  1. 通过包(Package)查。java.util -> Interfaces -> List -> each(Closure closure)

  2. 通过索引(Index)查。Index -> 页面搜索each(groovy.lang.Closure)(MacChrome浏览器快捷键Command+F) -> 找到Method in interface java.util.List一项

最终结果如下:

List的each方法详情

描述说是迭代一个List,并将每个子项作为参数传递到闭包中进行处理。

新增的Groovy类 API

Groovy - An agile dynamic language for the Java Platform
(GroovyDoc for Groovy and Java classes)

上面说的是Groovy and Java classes文档,包括Groovy类和原生Java类(可通过文档中的类的链接查看)。尤其要注意,这个文档中的JDK API点击后都会链接到原始的Java类,而不是Groovy化的Java类。
查看某个API详情的方法与上面的相同,略。


示例-Map语法


创建Gradle项目,并添加名为groovySyntax的任务

$ mkdir groovy-syntax
$ cd groovy-syntax
$ vi build.gradle

build.gradle文件

task(groovySyntax).doLast {
    println 'start groovy syntax task'
    doMap()
}

def doMap() {
    def emptyMap = [:]
    def test = ["id":1, "name":"zhangliang", "isMale":true]
    test["id"] = 2
    test.id = 900
    println test.id
    println test.isMale
    println test

    test.each { key ,value ->
        println "key=$key, value=$value"
    }

    test.each { entry ->
        println "entry->$entry,${entry.key}, ${entry.value}"
    }
}

执行gradle groovySyntax,输出如下

Starting a Gradle Daemon (subsequent builds will be faster)

> Task :groovySyntax
start groovy syntax task
900
true
{id=900, name=zhangliang, isMale=true}
key=id, value=900
key=name, value=zhangliang
key=isMale, value=true
entry->id=900,id, 900
entry->name=zhangliang,name, zhangliang
entry->isMale=true,isMale, true

BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

上面的代码和输出结果不难理解,分析如下:

  1. 方法没有嵌套时,括号可以省略。println 'start groovy syntax task'test.each{...}写全就是println('start groovy syntax task)'test.each({...})
  2. Map的定义参见语言规范-Map
  3. Map的方法each(Closure closure)的API文档说明如下

Allows a Map to be iterated through using a closure. If the closure takes one parameter then it will be passed the Map.Entry otherwise if the closure takes two parameters then it will be passed the key and the value.
可以用一个闭包来迭代Map,闭包的参数如果是一个就作为Map.Entry,如果两个参数就作为keyvalue


示例-修改Android项目输出的APK名称


Android开发中,打包完后修改apk的名称是一个比较常见的做法。之前开发的Android项目中,在app/build.gradle中加入了几行代码,每次打包后自动修改apk的名称,相关代码如下:
app/build.gradle


...

// 利用git commit count 作为构建号
static def gitBuildCode() {
    def cmd = 'git rev-list HEAD --first-parent --count'
    cmd.execute().text.trim().toInteger()
}

static def appName() {
    return "youchat"
}

// 修改输出文件的名称
android.applicationVariants.all { variant ->
    variant.outputs.all {
        if (outputFileName != null && outputFileName.endsWith('.apk')) {
            def endStr = outputFileName
            if (outputFileName.contains("debug")) {
                endStr = "debug.apk"
            } else if (outputFileName.contains("preRelease")) {
                endStr = "preRelease.apk"
            } else if (outputFileName.contains("release")) {
                endStr = "release.apk"
            }
            outputFileName = "${appName()}_${android.defaultConfig.versionName}_${gitBuildCode()}_${endStr}"
        }
    }
}

...

打包完后,可以得到类似下面的文件
app/build/outputs/apk/preRelease/youchat_7.5.0_999_preRelease.apk
上面的代码逻辑比较简单,简单分析如下:

  1. 定义了两个方法。gitBuildCode ()方法没有写return关键字,因为在Groovy中,方法总会返回值的,如果没有写return,就返回最后一行产生的值。参见语言规范-Object orientation-Method

Methods in Groovy always return some value. If no return statement is provided, the value evaluated in the last line executed will be returned

  1. android.applicationVariants.all(Closure var1)variant.outputs.all(Closure var1)是Gradle DSL语法,可以查看它的javadoc

Executes the given closure against all objects in this collection, and any objects subsequently added to this collection. The object is passed to the closure as the closure delegate. Alternatively, it is also passed as a parameter.
迭代容器中所有的对象,并传递给闭包进行处理。

  1. variant.outputs.all(Closure var1)闭包中的代码逻辑是很简单的,只说下最后一行outputFileName的赋值语句,它使用了字符串插值语法${},与kotlin里字符串模板是类似的。


参考


  1. Groovy 官网
  2. Apache Groovy Documentation
  3. 任玉刚 Gradle从入门到实战 - Groovy基础
  4. Gradle DSL Javadoc
  5. 使用Groovy开发之新特性
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 导语: 随着技术的发展,不管是前端开发、服务端开发或者是移动端开发(移动也是前端的一个分支)中都会用到自动化构建工...
    伊始雨深阅读 3,019评论 0 4
  • Groovy :是一种动态语言。 1:这种语言比较有特点,它和 Java 一样,也运行于 Java 虚拟机中。简单...
    PeytonWu阅读 1,543评论 0 1
  • 说明 本文主要从实现原理和代码层面介绍Gradle开发相关知识。关于本文中提到的、Gradle中的基本概念等内容,...
    jzj1993阅读 7,872评论 1 33
  • 三花齐聚顶 一叶渡江来 绘画:乔伊乔一
    石竹阅读 596评论 6 6