Gradle构建脚本使用Groovy来编写。默认的构建文件名为build.gradle 。Gradle命令在构建时,会寻找一份名为build.gradle的文件,然后执行。

在android studio项目中,默认情况下,根目录有一份build.gradle ,各个module也各有一份。

在android studio项目里的任意一份build.gradle文件里定义一个hello任务,执行gradle命令时,就会在这些build.gradle文件中寻找所有定义的hello任务,从根目录开始逐个执行,如:
在根目录的build.gradle文件中定义:

task hello {println 'Hello world root'
}

在app module目录的build.gradle文件中定义:

task hello {println 'Hello world app'
}
  • 在build.gradle所在目录使用gradle命令运行这个task
juk@Juk-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q hello
Hello world root
Hello world app
  • 也可以直接运行项目,然后在build的日志窗口可以看到输出

Gradle构建脚本中的Project对象

Project对象是实现了org.gradle.api.Project接口的对象。在build.gradle这个脚本中, 我们就会使用Project对象与Gradle构建命令打交道。通过它,我们访问很多Gradle提供的功能特性。

build.gradle文件与Project对象有一个一对一的关系。在构建初始化时,gradle会为每一个参与到构建中来的项目模块(module)组装一个Project对象,具体过程是这样的:

  1. 首先,为本次构建,创建org.gradle.api.initialization.Settings实例。执行settings.gradle脚本中的内容,并对Settings对象进行配置。它主要声明一些配置,用于实例化和配置参与构建的Project对象的层次。一个Settings对象对应于一份settings.gradle文件。这一步是在开始构建前完成的。
  2. 使用配置好的Settings对象创建Project实例的层次
  3. 最后,通过执行各个项目(module)的build.gradle配置各自的Project对象。执行的顺序,默认情况是从父项目(父module)再到子项目(子module)。

build.gradle的组成

一般,一个项目(module)对应一份build.gradle脚本。我们会用build.gradle脚本去配置Project对象。所以 build.gradle的组成就是Project对象的组成。

Tasks

一个Project对象基本上就是Tasks对象的集合。每个task都执行一些基本的工作,如编译类,运行单元测试,压缩WAR包,生成JavaDoc。每个task都属于某一个Project对象。Task对象是由TaskContainer对象负责创建的,在脚本中可以直接使用task的名字直接调用。在构建脚本中使用task关键字就可以声明task了:

task helloTask
task helloTask {}
task helloTask(type:Delete)
task helloTask(type:Delete){}
// 创建hello1 task
task(hello1) {println "Good morning!1"
}
// 创建hello2 task
task('hello2') {println "Good morning!"
}
// 创建hello3 task
tasks.create(name:'hello3') {println "Good afternoon!"
}

上面这些声明都是合法的

一个task是由一系列的行为对象组成的。当task被执行时,它们就会依次被执行。

task 的依赖关系

给task hello2添加一个依赖

task hello1 {doLast {println 'Hello world 1'}
}task hello2(dependsOn: 'hello1') {doLast {println 'Hello world 2'}
}

上面这种方式还可以换成以下这种方式:

task hello2 {doLast {println 'Hello world 2'}
}task hello1 {doLast {println 'Hello world 1'}
}hello2.dependsOn hello1

依赖还可以这样来写:


task hello2 {doLast {println 'Hello world 2'}
}task hello1 {doLast {println 'Hello world 1'}
}hello2.dependsOn {tasks.findAll {taskIt -> taskIt.name.startsWith('hello1')}
}

运行结果都是:

juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q hello2
Hello world 1
Hello world 2

doLast的意思就是将这个task 行为放到task的行为列表的最后面。

根据某些情况跳过task的执行

project.ext.skipStage = 'Hello'
task skipTask {doLast {println 'Hello world'}
}// 当有这个skipStage属性时才执行skipTask,没有时跳过skipTask,因当前面有定义skipStage这个属性,因此会执行skipTask
skipTask.onlyIf{project.hasProperty('skipStage')
}

还可以通过抛异常的方式来跳过,如上面的代码可以换成下面的来实现:

project.ext.skipStage = 'Hello'
task skipTask {doLast {println 'Hello world'}
}skipTask.doFirst {if(!project.hasProperty('skipStage')){throw new StopExecutionException()}
}

结果都是:

juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q skipTask
Hello world

在它要执行task之前,Gradle会经历不同的阶段。首先是配置阶段,过后就是执行阶段,这个阶段它就会执行task的doFirst或doLast闭包里的代码。

这里要给大家说明一下, 下面这种task的写法是OK的:

task hello {println 'Hello world 1'
}hello {println 'Hello world 2'
}

结果:

juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q hello
Hello world 1
Hello world 2

Dependencies

依赖配置应该是大家最熟悉的了。最常见就是下面这些:

dependencies {// 只能在当前项目(module)使用implementation 'group:name:version'// 共享api 'group:name:version'// 单元测试testImplementation 'group:name:version'// android测试androidTestImplementation 'group:name:version'...
}

在脚本就是这样配置的,它在Project对象中是由DependencyHandler对象管着的。

Repositories

指定外部依赖的源,就是告诉gradle去这个仓库下载我们添加的依赖。

repositories {google()mavenCentral()}

指定自己的依赖仓库,也是用这个

repositories {maven {url "http://repo.juk.com/maven2"}}

在脚本中配置的这些会用来配置在Project对象中的RepositoryHandler对象管着的。

如果你要上传你压缩包到maven仓库,那么你可以在maven插件的uploadArchives task用repositories指定上传位置

apply plugin: 'maven' // 要先把maven插件加进来,否则没有uploadArchives任务
uploadArchives {repositories {mavenDeployer {repository(url: "http://repo.juk.com/maven2")}}
}

Plugins

其实插件并没有什么特殊之处,它就是一些task的集合,例如有些插件里有编译的task,设置源文件的task设置等等。添加插件到项目中来其实就是为了扩充Project对象的能力,让它能做更多事。android项目的build.gradle就会有如下的插件:

plugins {id 'com.android.application'id 'kotlin-android'
}

一般来说插件有两种类型:

  1. 一种是脚本插件,它是一构建脚本,会用于构建过程中。
  2. 另一种是二进制插件,它们是一些实现了插件接口的类,通过程序的方法来控制构建。

对应的,添加插件也有两种方式:

  1. 从本地文件系统添加一份脚本
apply from: 'other.gradle'
  1. 添加二进制插件
plugins {id 'com.android.application'
}

apply plugin: 'com.android.application'

自定义一个插件

首先在build.gradle的开头引用我们的插件

apply plugin: HelloPlugin

然后在build.gradle找一个地方定义我们的插件,如文件末尾:

class HelloPlugin implements Plugin<Project> {@Overridevoid apply(Project project) {project.task("myHelloTask") {doLast {println 'Hello,My first plugin!'}}}
}

如你所见,自定义的插件,需要实现Plugin接口,apply方法的参数,就是当前build.gradle脚本对应的Project对象,从我们定义里可以看出我们往Project对象里添加了一个task,名为myHelloTask,我们也可以通过传进来的project对象去访问它的东西,如定义的属性。 我们来运行一下这个task:

juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q myHelloTask
Hello,My first plugin!

如何从build.gradle中获得输入?我们可以扩展Project对象,然后通过扩展后的对象来实现,具体如下:

apply plugin: HelloPlugin...// step 2:使用插件扩展出来的属性对象设置它的属性值
myParameter.message = 'Halo Wo'class HelloPlugin implements Plugin<Project> {@Overridevoid apply(Project project) {// step 1:在Project对象中扩展一个属性 myParameter,类型是我们定义的HelloPluginExtensionproject.extensions.create('myParameter',HelloPluginExtension)project.task("myHelloTask") {doLast {// step 3: 获取build.gradle输入的值println project.myParameter.message}}}
}class HelloPluginExtension {def String message = 'hello plugin'
}

运行任务myHelloTask:

juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q myHelloTask
Halo Wo

注意:在Gradle的版本中已有很多标准插件,如编程语言插件:java ,scala,assembler, c,cpp

例如要引用CPP插件:

apply plugin: cpp

查看构建信息

  • 查看Project对象的层次结构
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q projects   ------------------------------------------------------------
Root project 'HelloWorld'
------------------------------------------------------------Root project 'HelloWorld'
+--- Project ':app'
\--- Project ':houseware'To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :app:tasks
  • 查看任务
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q tasks   ------------------------------------------------------------
Tasks runnable from root project 'HelloWorld'
------------------------------------------------------------Android tasks
-------------
androidDependencies - Displays the Android dependencies of the project.
signingReport - Displays the signing info for the base and test modules
sourceSets - Prints out all the source sets defined in this project.Build tasks
-----------
assemble - Assemble main outputs for all the variants.
assembleAndroidTest - Assembles all the Test applications.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildKotlinToolingMetadata - Build metadata json file containing information about the used Kotlin tooling
buildNeeded - Assembles and tests this project and all projects it depends on.
bundle - Assemble bundles for all the variants.
clean - Deletes the build directory.
......

当然你也可以指定看某个项目的task,如houseware项目的task

juklinglee@JukLings-MacBook-Pro HelloWorld % /Users/juklinglee/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q :houseware:tasks------------------------------------------------------------
Tasks runnable from project ':houseware'
------------------------------------------------------------Android tasks
-------------
androidDependencies - Displays the Android dependencies of the project.
signingReport - Displays the signing info for the base and test modules
sourceSets - Prints out all the source sets defined in this project.Build tasks
-----------
assemble - Assemble main outputs for all the variants.
assembleAndroidTest - Assembles all the Test applications.
build - Assembles and tests this project.
......
  • 查看所有属性值
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q properties  ------------------------------------------------------------
Root project 'HelloWorld'
------------------------------------------------------------AGP_INTERNAL__MIN_PLUGIN_VERSION_CHECK_STARTED: true
_internalAndroidGradlePluginDependencyCheckerRegistered: true
allprojects: [root project 'HelloWorld', project ':app', project ':houseware']
android.enableJetifier: true
android.useAndroidX: true
ant: org.gradle.api.internal.project.DefaultAntBuilder@62b07301
antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@3dbfb745
artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@4bbf11cf
asDynamicObject: DynamicObject for root project 'HelloWorld'
baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@187dbbc2
buildDir: /Users/juklinglee/AndroidStudioProjects/HelloWorld/build
buildFile: /Users/juklinglee/AndroidStudioProjects/HelloWorld/build.gradle
......
  • 查看编译环境
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q buildEnvironment------------------------------------------------------------
Root project 'HelloWorld'
------------------------------------------------------------classpath
+--- com.android.tools.build:gradle:7.1.2
|    +--- com.android.tools:sdk-common:30.1.2
|    |    +--- com.android.tools:sdklib:30.1.2
|    |    |    +--- com.android.tools.layoutlib:layoutlib-api:30.1.2
|    |    |    |    +--- com.android.tools:common:30.1.2
|    |    |    |    |    +--- com.android.tools:annotations:30.1.2
|    |    |    |    |    +--- com.google.guava:guava:30.1-jre
|    |    |    |    |    |    +--- com.google.guava:failureaccess:1.0.1
|    |    |
  • 查看某个task的详细使用信息,如查看build 任务:
juklinglee@JukLings-MacBook-Pro HelloWorld % /Users/juklinglee/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle help --task build      > Configure project :app
C/C++: Could not execute cmake at
......
> Task :help
Detailed task information for buildPaths:app:build:houseware:buildTypeTask (org.gradle.api.Task)DescriptionAssembles and tests this project.Groupbuild

现在,通过查询我们知道build任务就是用来构建项目的。

最后,以上内容只是gradle的冰山一角,但是看它的源码,你将能很好的理解它是怎么工作的。
Gradle Github地址

Android Gradle构建脚本相关推荐

  1. 【AOP 面向切面编程】Android Studio 中配置 AspectJ ( 下载并配置AS中 jar 包 | 配置 Gradle 和 Gradle 插件版本 | 配置 Gradle 构建脚本 )

    文章目录 一.AspectJ 下载 二.拷贝 aspectjrt.jar 到 Android Studio 三.配置 Gradle 和 Gradle 插件版本 四.配置 Gradle 构建脚本 一.A ...

  2. 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 拷贝 lib7zr.so 动态库到 Android Studio 工程 | 配置 build.gradle 构建脚本 )

    文章目录 一.拷贝 lib7zr.so 动态库到 Android Studio 工程 二.配置 Module 下的 build.gradle 构建脚本 三.参考资料 一.拷贝 lib7zr.so 动态 ...

  3. Android Gradle 构建工具(Android Gradle Build Tools)是什么?

    转载地址:http://mrfu.me/android/2015/07/17/New_Android_Gradle_Build_Tools/ 译者地址:[翻]一览新的 Android Gradle 构 ...

  4. Gradle构建脚本概要之构建块

    为什么80%的码农都做不了架构师?>>>    每个Gradle构建都包含三个基本构建块:project,task和property.每个构建至少一个project,进而又包含一个或 ...

  5. 【CMake】CMake 引入 ( Android NDK 构建脚本 | CMake 命令手册 )

    文章目录 一.Android NDK 构建脚本 二.CMake 构建脚本示例 三.CMake 命令手册 1.CMake 脚本命令 2.CMake 工程命令 该系列博客的应用场景是 Android St ...

  6. Gradle构建脚本入门

    黄少存,叩丁狼高级讲师,本文为原创文章,转载请注明出处.   上一篇咱们已经知道了Gradle构建脚本的重要性,要使用比较复杂的项目构建就需要来书写构建脚本,那Gradle 的构建脚本有哪些呢,请看构 ...

  7. Android Gradle 学习笔记(四):Gradle 构建脚本

    本节我们从整体的角度来介绍一下Gradle. 一.setting.gradle 在Gradle中,定义了一个设置文件,用于初始化以及工程树的配置.设置文件的默认的名字就是setting.gradle, ...

  8. Android Studio Gradle构建脚本

    Gradle是一种依赖管理工具,基于Groovy语言,面向Java应用为主,它抛弃了基于XML的各种繁琐配置,取而代之的是一种基于Groovy的内部领域特定(DSL)语言. 构建工具就是对你的项目进行 ...

  9. android定义全局变量,Android Gradle构建:如何设置全局变量

    另外,对于动态全局变量,可以在主2733457354657357367040文件中定义全局函数: 首先,定义您的函数,例如git branch: def getGitBranch = { -> ...

  10. gradle构建脚本、依赖、插件管理、生命周期进阶教程

最新文章

  1. ecshop商品详情相册顺序调整
  2. 机器学习基础专题:线性回归
  3. 【Paper】2019_Bearing-only circumnavigation control of the multi-agent system around a moving target
  4. java 日历类_JAVA 的日历类型
  5. Android ListView几个重要属性
  6. 造轮子-AgileConfig一个基于.NetCore开发的轻量级配置中心
  7. linux忘记mysql密码_Linux下忘记Mysql密码的找回方法(图)
  8. java中匿名类的注意细节
  9. div和img之间的缝隙问题
  10. MongoDB University课程M103 Basic Cluster Administration 学习笔记
  11. matlab功能特点,MATLAB的特点及应用领域
  12. 快进来看程序员风格的修真小说!
  13. 斑马电商云品牌发布会就是一群有梦想的人在搞事情
  14. 【AMAD】django-filer -- 一个管理文件和图片的django app
  15. 洛谷月赛T2 P6858[深海少女与胖头鱼]题解
  16. centos关闭自动锁屏
  17. 23 SpringBoot @Qualifier注解
  18. Excel中VBA编程学习笔记(十一)--正则表达式
  19. word2vec你可能不知道的秘密
  20. 我国计算机发展优势,浅析我国计算机应用发展.doc

热门文章

  1. Hibernate中的一级缓存、二级缓存和懒加载
  2. 抑郁症,恐惧,压力和肠道微生物群脱不开的关系
  3. Python笔记:第三方IP代理服务与爬虫IP代理
  4. 阿里云封禁端口25,导致smtp.126.com邮件无法发送-解决方案+springboot配置
  5. QT学习 实时显示时间
  6. DS18B20数字温度计 (二) 测温, ROM和CRC算法
  7. BOM Routing (2009-08-31 23:46:00)
  8. 推荐好用的两个搜索下载书籍网站
  9. word使用上角标超链接到引用的参考论文
  10. 从「广义斯托克斯公式」结合「外微分公式」导出「牛顿-莱布尼茨公式」、「格林公式」、「高斯公式」、「斯托克斯公式」