Android Gradle—了解Gradle及自动化构建

前言

本专栏内容主要分为两大部分:

  1. Groovy基础到进阶
  2. Gradle开发及Gradle在Android中的使用。

本专栏内容尽量做到覆盖全满,不遗漏知识点。

  1. 对于Groovy的学习会基于已掌握的Java及Kotlin语言,通过对比分析来提高学习效率。
  2. 对于Gradle的内容我们主要针对在Android开发中的实际使用来进行讲解,做到学以致用的目的。

1. Gradle介绍

  • Gradle是一款基于Apache的Ant和Maven概念的项目自动化开源构建工具。Gradle的核心是基于Java来实现的,可以把Gradle看成就是一个轻量级的Java应用程序。
  • Gradle是使用Groovy、Kotlin等语言编写自定义脚本,取代了Ant和Maven使用xml配置文件的方式,很大程度简化了开发时对项目构建要做的配置,使用更加灵活和强大。

1.1 为什么要学习Gradle

Gradle不仅是目前Andorid最主流的构建工具。而且不少技术领域如组件化、插件化、热修复,及构建系统 (很多优秀的框架都是在编译时或者打包之前做一些特殊的处理) ,都需要通过Gradle来实现,不懂Gradle将无法完成上述事情,所以学习Gradle非常必要。

1.2 关于项目构建

  1. 对于Java应用程序,编写好的Java代码需要编译成.class文件才能够执行。所以任何的Java应用开发,最终都需要经过这一步;
  2. 编译好了这些class文件,还需要对其进行打包。打包不仅针对于这些class文件,还有所有的资源文件等。比如web工程打包成jar包或者war包就包含了自己的资源文件,然后放到服务器上运行。
  3. Andorid工程编译好的class文件还要被打包到dex包中,并且所有的资源文件进行合并处理,甚至还需要对最终打包出来的文件进行加密和签名处理等等。

图解说明

1.3 自动化构建工具的发展

  1. “石器时代”:自己编写命令脚本,进行编译和打包
  2. “蒸汽时代”:Make、Ant工具的出现
  3. “电气时代”:Maven
  4. “信息时代”:Gradle,更高级的自动构建工具出现 ...

1.4 Gradle提供了什么

  • 对多工程的构建支持非常出色,尤其是工程依赖问题,并支持局部构建;
  • 多种方式的依赖管理:如远程Maven仓库,nexus私服,ivy仓库或者本地文件系统等;
  • 支持传递性依赖管理;
  • 轻松迁移项目工程;
  • 基于Groovy等语言构建脚本,简便且灵活;
  • 免费开源,并且整体设计是以作为一种语言为导向的,而非成为一个严格死板的框架。

上面我们提到, Gradle是使用Groovy、Kotlin等语言编写自定义脚本,现在我们了解了Gradle相关的,接下来将介绍 Groovy。

2. Groovy介绍

Groovy是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy代码能够与Java代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy也可以使用其它非Java语言编写的库。

这里我们提到,Groovy代码能够与Java代码很好地结合,然后现在Android开发也慢慢往 Kotlin 发展,那么我们看看这三者的区别。

2.1 Groovy & Java & Kotlin

  • Groovy、Java及Kotlin都是基于JVM的开发语言;
  • Groovy基于Java,在语法上基本相似,但也做了很多自己的扩展。Groovy除了可以面向对象编程,还可以用作纯粹的脚本语言,这一点和Kotlin是一样的;
  • Goovy 和 Kotlin都有自己支持的DSL,两者有许多共通之处。

这里有一组比较有意思的对话:

Groovy:我不是针对Java,而是所有不能愉快写DSL的都是laji。
Clojure:我真的不是针对Java,只是关于并发,我有一个大胆的想法。
Scala:我也真的不是针对Java,只是关于并发,我还有一种大胆的想法。
Kotlin:我就是处处针对Java!
Java退出了群聊...

满满感受到Java的无奈 :》

2.2 Groovy特性

  • 同时支持静态类型和动态类型;
  • 支持运算符重载;
  • 支持DSL语法特性;
  • 本地语法列表和关联数组;
  • 各种标记语言,如XML和HTML原生支持;
  • 对正则表达式的本地支持;
  • Groovy和Java语法非常相似,可以无缝衔接使用Java;
  • 支持使用现有的Java库,并做了一定的扩展。

这里说到,Groovy和Java语法非常相似,可以无缝衔接使用Java,那我们来看看是如何无缝衔接的。

3. 从Java到Groovy

注:开发环境为:Idea+Groovy环境,所以开发者需要额外在Idea编译器里面配置Groovy环境。

如图所示

创建项目时选择Groovy选项,可以不用勾选Kotlin环境直接创建,毕竟要看如何从Java到Groovy。这里分别举几个比较常用的例子。

3.1 对应第一个项目

class HelloGroovy {
    static void main(String[] args) {
        System.out.println("hello Groovy!");
    }
}

这是很标准的第一项java项目。接下来我们看看 Groovy 的第一个项目

def test() {
    "hello Groovy!" //方法返回值不用写return,已最后一句话代码作为方法的返回类型
}

println(test()) //代码末尾可以省略 分号

println test() //打印甚至还能省略外面的一对大括号。

接下来看看我们经常用的循环:

3.2 对应的循环

class HelloGroovy {
    static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            System.out.print(i+"\t ha")
        }
//        System.out.println("hello Groovy!")
    }
}

这里不用多说了,java大家都熟悉。现在看看Groovy的语法。

3.times {
    println it+"\t haha"
}

或者

(0..2).forEach{
    println it+"\t haha"
}

运行效果

0    haha
1    haha
2    haha

熟悉Kotlin的小伙伴应该能够秒懂这段代码,毕竟 kotlin 是在 groovy基础上进阶改良的,所以作为 Kotlin的前辈,语法几乎都是类似的。

3.3 对应的安全操作符

我们就以最经典的非空判断为准。

class HelloGroovy {

    static String toUpperCase(String content) {
        if (content == null || content.length() == 0) {
             return "null";
        }
        content = content.toUpperCase();
        return content;
    }

    static void main(String[] args) {
        String content = "abc";
        System.out.println(toUpperCase(content));
    }

}

这里很经典的非空判断,不为空就转大写。接下来看看Groovy对应的

def toUpperCase(str) {
    str?.toUpperCase()
}

println toUpperCase("abc")
println toUpperCase(null)

Groovy运行效果

ABC
null

学过Kotlin的小伙伴都知道,Kotlin代码自带非空检测,只要可能为空的部分就必须让开发者处理,否则连编译都不能通过。要想通过编译,要么处理为永不为空,要么调用前加一个问号,表示为空就不执行。这里的 Groovy 语法和Kotlin 一样。

3.4 数据类型

在开发中我们定义对应的变量,肯定离不开对应的数据类型。在我们熟悉的Java中,我们所使用的基本数据类型都会有装箱拆箱的操作,比如说。

  • 基本数据类型

    byte、short、int、long、float、double、char、boolean

  • 包装类(装箱、拆箱)

    String、Byte、Short、Integer、Long、Float、Double、Char、Boolean

而在Groovy中,因为它具有动态类的特性,所以它从一开始就支持自动装箱实际上,必要时Groovy会自动将基本类型视作对象

3.5 字符串

Java大家都再熟悉不过了,后面就直接开始贴Groovy的代码。

def name = 'carName'
def realName = "$name:AAAA"
println name.getClass()
println realName.getClass()
def string='''
carName
is
$name
'''
println string

运行效果

class java.lang.String
class org.codehaus.groovy.runtime.GStringImpl

carName
is
$name

Process finished with exit code 0

从这里可以看出:

  • 单引号字符串是java.lang.String类型,同时不支持插值
  • 双引号字符串在没有使用插值表达式情况下是java.lang.String类型, 但如果有插值表达式使用的话,就是groovy.lang.GString类型
  • 三引号字符串表示多行的字符串。不必将字符串分割成几块,也不必用连接符或换行符转义字符来将字符串跨行

3.6 数组和列表

def array = ["1", "2", 3]
println array.getClass()
// int []
String[] array2 = ["1",new Object(),2, "3"]
//def array2 = [1, 2, 3] as int[]
println array2.getClass()

println array2[1].toString()
println array2[1].getClass()

可以看出,这里定义了一个集合和一个数组,在集合和数组里面,我故意放入了不同类型的数据,代码也没有报错,我们运行看看效果。

class java.util.ArrayList
class [Ljava.lang.String;
java.lang.Object@3b4ef7
class java.lang.String

由此我们可得:

  • 数组和列表都是使用逗号分割列表的值,使用方括号括起来表示
  • Groovy中的数组和列可以随意转换
  • def定义的变量会自动推断 [ ] 类型是列表
  • Groovy列表是普通的JDK java.util.List,因为Groovy中没有定义自己的集合类

3.7 范围

范围是一种特殊的列表,由序列中的第一个和最后一个值表示,Range可以是包含或排除。包含范围包括从第一个到最后一个的所有值,而独占范围包括除最后一个之外的所有值。

(0..2).forEach{
    println it+"\t haha"
}
('a'..<'d').forEach{
    println it
}

def range = 0..10
println range.getClass()

运行效果

0    haha
1    haha
2    haha
a
b
c
class groovy.lang.IntRange
Process finished with exit code 0

由此我们可得:

  • 1..10 包含范围的示例
  • 1..<10 独占范围的示例 (开区间)

3.8 映射

映射(也称为关联数组,字典,表和散列)是对象引用的无序集合。Map集合中的元素由键值访问。Map中使用的键可以是任何类,如果不能推断具体key类型,默认就是字符串。

在Groovy中可以使用特定的表述方式来指定映射

// [k1:v1,k2:v2]
def map = [a: 11, b: 12]
map.forEach { k, v ->
    println "key=${k.class} , value=$v"
}

def value = map['a']
println value

运行效果

key=class java.lang.String , value=11
key=class java.lang.String , value=12
11

由此我们可得:[k1:v1,k2:v2] 具有键值对的集合。

最后

您的点赞收藏就是对我最大的鼓励! 欢迎关注我,分享Android干货,交流Android技术。 对文章有何见解,或者有何技术问题,欢迎在评论区一起留言讨论!最后给大家分享一些Android相关的视频教程,感兴趣的朋友可以去看看。

本文转自 https://juejin.cn/post/7020709822630723621,如有侵权,请联系删除。

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

推荐阅读更多精彩内容