Gradle-构建脚本

Gradle 构建配置脚本常识科普


构建脚本.png

构建语言

Gradle提供了一种领域特定语言,目前同时支持 Groovy 和 Kotlin 。

在 Groovy 构建脚本中(.gradle) 你可以使用任何 Groovy 元素。

在 Kotlin 构建脚本中 (.gradle.kts) 你可以使用任何 Kotlin 元素。

项目(Project) 和 任务(Task)

Gradle 构建的一切都是基于 两个概念 :项目 和任务;

一个构建是由一个或多个项目组成的。项目的概念比较抽象,你可以创建一个 Project 用于生成一个 jar,也可以定义个项目用于生成 war 包,还可以定义一个项目用于发布上传你的 war等。

一个项目就是在你的业务范围内,被你抽象出来的一个独立的模块,你可以根据工程的实际情况抽象归类,最后这一个个的 项目组成了整个 Gradle 构建。

一个 项目又包含很多个任务,每个项目是由一个或多个任务组成的。任务就是一个操作,一个原子性的操作。比如打个 jar 包,复制一份文件,编译一次 java 代码等,这就是一个任务。

build.gradle & Project API

每个项目都有一个 build.gradle 文件,该文件是该项目的构建入口,可以在这这个文件里对该项目进行配置,比如配置版本,需要哪些插件,依赖哪些库等。

我们通过配置这个文件描述我们的构建,这其实就是一个配置脚本。

每一个脚本在执行的时候都会被关联到一个 Project 实例上。

在构建生命周期的初始化阶段,Gradle 会为每个项目创建一个 Project 实例,并根据 build.gradle的内容配置这个实例。

也就是说每个 build.gradle 的配置都会被配置到 Project 实例上。

实际上,build.gradle 中几乎所有的顶级属性和代码块都是 Project 类的 API,

下面通过访问 Project.name 属性验证一下。

在 build.gradle

println "name is $name"
println "project.name is ${project.name}"

执行 build 任务,你将会得到下面的输出,输出的值都是 项目的名字


验证输出

第一条语句使用的是Project的顶级属性。

第二条语句使用的 project 属性 可以在脚本的任何地方访问,它代表的是当前脚本的Project对象。

只有在你定义了和Project的成员(方法,属性)同名的时候才需要使用 project ,其他时候直接使用 名称即可访问,例如第一条语句。

一个构建是由多个Project组成的,是通过项目树的形式表示的。

可以在项目树的根项目对所有的项目统一配置一些配置。例如,应用的插件,依赖的 Maven 中心库等。

为所有子项目配置仓库为 jcenter

subprojects{
    repositories {
        jcenter()
    }
}

也可以为所有子项目配置 使用 Java 插件

subprojects{
    apply plugin:'java'
    repositories {
        jcenter()
    }
}

除了 subprojects 还有 allprojects ,从名字就可以看出来这不仅是对子项目的配置而是对所有项目的配置。

这两个配置其实是两个方法,接受一个闭包参数,对项目进行遍历,遍历的过程中调用我们自定义的闭包,所以我们可以在闭包里配置,打印,输出或者修改 Project 的属性。

Project 的属性

Project 对象的属性在 脚本全局都是可以使用的。

下面列出一些常用的属性,更全的属性可以在 Project API 中查询。

名字 类型 默认值
project Project Project 实例
name String 项目名字
path String 项目的绝对路径
description String 项目描述
projectDir File 配置脚本所在的目录
buildDir File projectDir/build 输出目录
group Object 未指定
version Object 未指定
ant AntBuilder AntBuilder 实例

settings.gradle

这是一个设置文件,用于初始化以及项目树的配置。设置文件的默认名字就是 settings.gradle,放在根项目目录下。

关于构建生命周期和 settings.gradle 更详细的可以看我的这篇文章

script API

当 Gradle 执行 Groovy 脚本(.gradle)时,会编译脚本到实现了 Script 的类中。

也就是说,Script 接口中的所有属性和方法都可以在脚本中使用。

当 Gradle 执行 Kotlin 脚本(.gradle.kts)时,会编译脚本到 KotlinBuildScript的子类中。

也就是 KotlinBuildScript 类中的所有属性和方法都可以在脚本中使用。

更详细的可以参考 KotlinSettingsScriptKotlinInitScript 类,分别用于设置脚本和init脚本。

脚本即代码

虽然我们在一个 Gradle 文件里写脚本,但是我们写的都是代码,这一点一定要非常的清楚。

我们写的确实是脚本,但不是简单的脚本。在脚本里可以定义 Class ,内部类,导入包,定义方法、常量、接口等。

不要把它当作简单的脚本,我们可以灵活的使用 Java ,Groovy ,Kotlin 和 Gradle.

例如 定义一个获取当前日期的方法

def buildTime(){
    def date = new Date()
    def formattedDate = date.format('yyyyMMdd')
    return formattedDate
}

变量 & 额外的自定义属性

Gradle 支持两种变量 :局部变量和自定义属性

局部变量

局部变量使用 def 关键字声明,局部变量只能在声明的范围内可见。

def myName = '佛系编码'

额外的自定义属性

Gradle 领域模型中 所有的对象 都可以添加额外的自定义属性。

通过对象的 ext 属性实现对自定义属性的添加,访问,设置值的操作。

添加之后可以通过 ext 属性对自定义属性读取和设置,也可以同时添加多个自定义属性。

//为 project 添加一个 age 属性 并赋值 20
ext.age = 20

//为 project 添加两个属性
ext{
    phone =110
    address = '404'
}

task myTask {
    //为 myTask 任务添加属性
    ext.myProperty = "myValue"
}
task extra{
     doLast{
         println "project : age= ${project.ext.age},phone= ${project.ext.phone} , address = ${project.ext.address}"
         println "myTask :  ${myTask.myProperty}"
     }

}

创建一个任务

task hello {
    doLast {
        println 'Hello world!'
    }
}

这里的 task 看着像一个关键字,实际上是一个方法,这个方法的原型是 TaskContainer.create()

任务的创建就是使用这个方法给 Project 添加一个 Task 类型的属性;所以才能使用任务名字引用一些API,例如为任务添加额外的属性。

任务依赖和任务排序

一个任务可以依赖其他任务或者在其他任务执行后再执行。

Gradle 确保在执行任务时遵守所有任务依赖性和排序规则,以便在所有依赖项和任何 “必须运行” 的任务执行之后再执行任务。

Gradle 为我们提供了几个方法用来控制任务的依赖和排序,就是下面这几个

这些方法可以接收 任务,任务名字,路径等,具体参数可以在 Task文档 里查看

task hello {
    doLast {
        println 'Hello world!'
    }
}

task taskX {
    dependsOn hello
    doLast{
        println "I'm  $name."
    }
}

task taskY {
    doFirst {
        println "I'm $name."
    }
}

如果 taskX 要依赖 taskY 的话,并不能直接引用,因为 taskY 是在 taskX 之后定义的。

task taskX {
    dependsOn 'taskY'
    doLast{
        println "I'm  $name."
    }
}

默认任务

在没有指定执行任务的时候,可以在脚本中定义默认任务,使用 defaultTasks 方法

这个方法接收 字符串参数,传入任务的名称即可·

defaultTasks 'hello','taskY'

外部依赖

用添加外部依赖,必须添加依赖所在仓库。例如 jcenter,maven,google等

目前支持很多类型的仓库,基本上都在这里列出来,可以查看 仓库类型

添加 google 仓库

allprojects {
    repositories {
        mavenCentral()
        google()
        jcenter()
    }
}

在 Android 的项目中,这都是放在根项目里的 allprojects 方法里,对所有项目统一配置

添加外部依赖

dependencies {
    implementation 'io.reactivex.rxjava2:rxjava:2.1.2'
}

在 Android 中依赖的添加放在了各个module 中,按需添加,哪个模块需要在哪个模块的构建脚本里添加。

依赖属性分为三部分

  • group: 这个属性用来标识一个组织、公司或者项目,可以用点号分隔,例如上面的 io.reactivex.rxjava2
  • name: name属性唯一的描述了这个依赖,例如上面的 rxjava
  • version: 一个库可以有很多个版本。例如上面的 2.1.2

其中 implementation 为配置项,配置也有很多种类型,下面贴出来一张来自 Google 的说明:详情可以查看这个 依赖项配置

依赖配置.png

最后是 DSL 的API 地址 https://docs.gradle.org/current/dsl/index.html

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

推荐阅读更多精彩内容

  • 从这章开始,会对Gradle有一个大概的介绍,帮助大家快速的入门Gradle。本章从整体构建脚本的角度介绍Grad...
    acc8226阅读 848评论 0 1
  • 本文作者:黄少存,叩丁狼高级讲师。原创文章,转载请注明出处。 上一篇咱们已经知道了Gradle构建脚本的重要性,要...
    叩丁狼教育阅读 451评论 0 0
  • 文章来源 上一篇咱们已经知道了Gradle构建脚本的重要性,要使用比较复杂的项目构建就需要来书写构建脚本,那Gra...
    黄少存阅读 675评论 0 1
  • 上一篇我们已经知道了Gradle构建脚本的重要性,要使用比较复杂的项目构建就需要来书写构建脚本,那Gradle 的...
    Java_Explorer阅读 482评论 0 0
  • 今年清明节不同往年,我没有躺在寝室。 我听着他发过来带着北方口音的语音,说转十六号线坐到倒二站,然后他...
    zhou未阅读 270评论 0 0