关于Gradle的构建流程,2024年Android工作或许更难找

每一个Gradle的构建都是从一个脚本开始的,构建脚本的默认名字是build.gradle,当在shell中执行gradle命令时,Gradle就会去寻找这个build.gradle的文件。如果找不到就会显示一个帮助信息。

在这里插入图片描述

在app文件下的build.gradle文件中定义一个原子工作,在上图中 task在Gradle中就是构建一个任务,这个任务是输出helloworld,下面在Terminal执行gradle hello(gradle taskname):

在这里插入图片描述

通过gradle -q hello可以加快执行速度(通过命令选项quiet,只需执行里面代码,省去了一些记录别的东西的操作)

task和里面的action是groovy这门语言的重要元素,doLast就是一个action,表示这个action最后执行,也可以用 符号<<来表示doLast:

在这里插入图片描述

下面展示Gradle更高级的特性:

在这里插入图片描述

代码中 dependsOn来说明task之间的依赖。

Gradle会确保被依赖的task总会在定义该依赖的task之前执行。

dependsOn是task的一个方法,比如我们执行最后一行的groupThreapy,它里面依赖了mGradle2,所以会先执行mGradle2,但是mGradle2又依赖了mGradle1和mGradle0,所以在执行mGradle2前会先执行mG1和mG0,而mG0依赖了startTaskeone,所以最开始就会先执行startTaskone。

Gradle可以很好的和Ant(是一个java的构建工具)去集成,因为拥有对Groovy语言特性的完全访问权,所以用write()来打印信息。每个脚本都带有一个ant属性,赋予了可以直接访问Ant任务的能力。上面的例子中可以使用Ant的任务echo去打印"Gradle"。

另外Gradle提供的一个特性就是定义动态task,就是指向运行中指定任务的名字。在上述例子中,使用了Groovy的times方法创建了3个task。Groovy自动暴露一个隐式变量it来指定循环迭代的次数,可以使用这个计数器来构建task的名字,对于第一次循环的task叫做mGradle0.

下面运行 grade groupTherapy:

在这里插入图片描述

从上面结果可以看出执行过程:

在这里插入图片描述

4、使用Gradle命令行


  1. 通过执行gradle -q tasks:列出项目中所有可用的task:

在这里插入图片描述

这个时候可能会产生:构建脚本中定义的其他task去哪了?

  1. 通过执行 gradle -q tasks --all 就可以列出项目内所有的task信息

在Other task中,就有这些定义的task啦(group Threapy、mGradle0…):

在这里插入图片描述

任务名字缩写

gradle另外一个特性就是能以驼峰式的缩写在命令行上运行任务,例如在上述例子中,可以执行

gradle mG0 gT一样可以运行:

在这里插入图片描述

当然如果出现两个相同缩写的方法,比如写一个gotest和groupThreapy缩写相同,则执行命令行会报错。

执行时排除任务

有时候在构建运行时,需要排除一个指定任务,这时候可以通过-x来实现,假设现在要排除mGradle0:

在这里插入图片描述

命令行选项:

  • gradle xxxx -is或者 gradle xxxx -i-s:打印出构建期间时的发生错误的堆栈追踪痕迹

  • gradle xxxx --help:打印出所有可用的命令行选项,描述信息

  • gradle -b xxx.gradle:可以执行一个特定的名字的构建脚本

  • gradle xxxx --offline:离线模式运行构建,仅仅在本地缓存检查依赖是否存在

守护进程

当每次和gradle打交道的时候,会发现我们每次都需要不断重复构建,每次初始化一个构建时,JVM都要重启一次,Gradle的依赖都要载入到类加载器中,而且还要建立项目对象模型,这个过程需要一段时间,这时候Gradle守护进程就是为了解决这个问题。

Gradle守护进程的出现就是以后台的方式运行Gradle,gradle命令就会在后续的构建之中重用之前的进程,避免了启动时造成的开销。

如何开启守护进程?我们在运行gradle命令时,加上--daemon选项,一旦启动就可以看看系统进程表(Max OS X或者linux就在shell中运行命令 ps | grep gradle ,Windows中直接用任务管理器查看):

通过 gradle mG0 gT --daemon 实践:

在这里插入图片描述

这时候查看任务管理器:

在这里插入图片描述

守护进程会在3个小时空闲时间自动过期,任何时候你都可以选择构建不适用守护进程,加上–no–daemon即可,如果手动停止进程,可以执行 gradle --stop命令。

下面展示如何在构建apk中,在Andorid Manifest.xml添加meta-data,用Gradle脚本自动完成:

(1)第一种方法,在app的build.gradle中编写,提前导入 import groovy.xml.*

在这里插入图片描述

然后在Terminal中输入:

在这里插入图片描述

接下来就可以在Manifest.xml中看到:

在这里插入图片描述

(2)第二种方法

导入两个类 import com.android.build.gradle.api.ApplicationVariant

import groovy.xml.XmlUtil

在这里插入图片描述

同样也是可以的。

Gradle的项目构建分为三个阶段:初始化、配置、执行。

5、Gradle初始化


在这个阶段中,Gradle决定哪些项目加入到构建中(因为Gradle支持多项目构建),并为这些项目分别创建一个Project实例。

Gradle支持多项目构建和单项目构建,如果是单项目构建,则初始化当前项目即可,如果是多项目构建,则需要决定哪些项目需要加入到构建中并初始化,那么Gradle是如何判断当前构建的是单项目还是多项目呢?如果是多项目,Gradle又是如何决定将哪些项目加入到构建中呢?

多项目还是单项目构建

这里的关键是一个名为settings.gradle,Gradle构建初会去寻找这个文件,查找的规则如下:

  1. 查找当前构建目录下的settings.gradle文件。

  2. 如果没有找到, 则去与当前目录有着相同嵌套级别的master目录查找

  3. 如果没有找到则去父目录中找

  4. 如果没有找到,则进行单项目构建

  5. 如果找到了,Gradle就检查这个文件中是否有定义,如果没有定义多项目,则进行单项目构建,否则进行多项目构建。

多项目工程根目录必须存在 settings.gradle文件中,单项目工程可以不需要这个目录。

多项目构建的项目集如何确定?

多项目构建时,项目集由settings.gradle中定义,项目集可以用一个树型结构表示,每个节点表示一个项目,并且有对应的项目路径。

下面就是一个多项目的settings.gradle文件:

include ‘project1’, ‘project2:child’, ‘project3:child1’

include方法接收多个项目路径作为参数。

每个项目路径对应文件系统中的一个目录,通常情况下项目路径和文件目录一一对应,比如project2:child就是对应project2/child目录。

如果项目树的叶节点和它的父节点都需要包含在构建中,则只需指定子节点即可。

比如project2:child,将创建两个项目实例 project2和project2:child

扁平化布局:

includeFlat ‘project3’, ‘project4’

includeFlat方法将目录作为参数,这些目录是根项目目录的兄弟项目,并作为多项目中根项目的子项目。

Settings语法

这里主要说一下include方法的语法,其余的语法请对应:传送门

settings.gradle在构建时会创建代理对象Settings,其include方法对应着Settings.include(java.lang.String[])

  1. include方法接收项目路径数组作为参数,并将对应的项目添加到构建中

  2. 参数中支持的项目路径分隔符为“:”而不是“/”

  3. 路径中最后一个节点是项目名称

  4. 项目路径是根项目 目录下的相对路径

可以使用ProjectDescription.setProjectDir(java.io.File)更改

示例:

// 引入两个项目, ‘foo’ and ‘foo:bar’

// 对应的文件目录是 $rootDir/a 和 $rootDir/a/b

// directories are inferred by replacing ‘:’ with ‘/’

include ‘foo:bar’

// include one project whose project dir does not match the logical project path

// 引入‘baz’项目,对应的文件目录是foo/baz

include ‘baz’

project(‘:baz’).projectDir = file(‘foo/baz’)

6、配置


默认情况下,Gradle会配置settings.gradle里的所有项目,不论这些项目与最终执行的任务是否有关。

项目配置按照广度配置(breath-wise)顺序配置,如父项目先于子项目配置。

按需配置模式

一个多项目构建中,可能存在大量无需配置的项目,如果需要配置所有的项目后才能运行程序, 则会浪费大量的时间,在Gradle1.4开始引入了按需配置模式。

在这个模式下,Gradle只配置与最终任务相关联的项目,以缩短构建时间,这个模式以后会成为默认模式。

按需配置模式下,项目配置遵循如下规则:

  • 根项目总会被配置

  • 构建的当前项目也会被配置

  • 项目的依赖会被配置

  • 任务依赖的对应项目会被配置(就是之前讲过的dependsOn)

  • 通过命令行构建任务时会配置相应的项目。比如构建 'project A:project B:someTask’时会配置projectB

进行构建时,可以在命令行加入gradle xxxx --config-on-deamon来指定按需配置模式来进行构建。

7、执行


在这个阶段之前,Gradle已经决定好了要构建的项目集,项目集由输入到命令行和当前目录决定的,然后Gradle会去执行任务集中的每个任务。

任务(Task)是由一系列活动(action)构成,当任务执行的时候,活动会依次执行。可以通过doFirst和doLast方法将活动添加到任务中。

那么在多项目构建时,Gradle是如何确定任务是哪个项目的?尤其是任务名称相同的情况下?

其次是Gradle如何确定多任务的执行顺序?

任务的位置

以命令行**$ gradle hello**为例,在执行阶段,Gradle会从构建的当前项目目录开始,依据项目树,往下查找名为 hello 的Task并执行,因此Gradle不会执行当前项目的父项目和兄弟项目的任务。

任务的顺序

如果没有额外的配置,Gradle将会以字母数字的顺序执行任务,比如“:consumer:action”将先于“:producer:action”执行

8、单项目构建示例


创建项目目录

$ mkdir single-project-build-lifecycle-demo

$ cd single-project-build-lifecycle-demo

创建settings.gradle文件

$ vi settings.gradle

在settings.gradle中:

rootProject.name = ‘single-project-build-lifecycle-demo’

println ‘settings.gradle -> this is executed during the initialization phase.’

创建build.gradle

创建build.gradle文件

$ vi build.gradle

println ‘build.gradle -> global println -> This is executed during the configuration phase.’

最后

文末放一个小福利给大家,点击我的GitHub即可领取

群内有许多技术大牛,有任何问题,欢迎广大网友一起来交流,群内还不定期免费分享高阶Android学习视频资料和面试资料包~

偷偷说一句:群里高手如云,欢迎大家加群和大佬们一起交流讨论啊!

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-L3GYf8qm-1711006894356)]
[外链图片转存中…(img-oTBFaxVh-1711006894357)]
[外链图片转存中…(img-0fkRDMSt-1711006894357)]
[外链图片转存中…(img-GCA2BbOD-1711006894358)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-lREfRvLa-1711006894358)]

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值