欢迎光临散文网 会员登陆 & 注册

DEVLOG 9.22 Gradle 笔记(1)Gradle重要概念扫盲

2021-09-24 09:18 作者:房顶上的铝皮水塔  | 我要投稿

构建生命周期

初始化 - 配置 - 执行

初始化阶段:

初始化阶段Gradle会根据根目录下面的settings.gradle构建Settings对象,settings.gradle会决定有哪些模块参与构建。构建工具会根据每一个build.gradle构建Project对象。根目录的build

.gradle可以理解为最顶层的Project,每一个模块中的Project可以通过rootProject访问根目录的Project对象。构建工具之后会根据Settings配置Project

配置阶段:

配置阶段Gradle会分析每一个Project的依赖关系。

举华师匣子2.0为例,华师匣子2.0中配置了很多不同的module,这些module的初衷是为了让业务分离,让开发者更注重于开发主要业务。如果存在不同的模块的话,维护起来会更加方便,但是这个解耦并不完全,因为我们并没有将不同的功能分成不同的模块。不同的模块之前的UI跳转需要使用Arouter实现,我们没有这样分,所以也没有真正的使用Arouter。

执行阶段:

执行阶段会执行Task。会按照Task的依赖顺序执行。


Project

build.gradle中使用的函数 DSL块不外乎都是Project以及它继承而来的方法。

application build.gradle 和 app build

application层级的build.gradle是最顶级的Project,里面包括了子Project,也就是app的build.gradle。当Gradle启动的时候,会先启动settings.gradle,生成Settings对象,然后再按照这个对象的要求配置build.gradle,include的相关代码就写在settings.gradle中。

子Project中定义的Task也可以被顶级Project访问到。假设我在app module中定义了这两个Task(hello 和 subTask)

使用如下命令可以在打印中找到这两个Task是属于app的:


每一个build.gradle 都代表着一个project,每个project都有若干个task。Task表示Gradle的一个原子性操作。

Task

Task表示一系列的Action ,因此可以使用doFirst或者doLast向Task中添加Action对象。Action是一个接口,使用的感觉其实上就是一个闭包

  1. Task的创建

在build.gradle中可以获取当前的Project的实例,并且可以通过tasks获取TaskContainer对象,然后就可以将新的Task加入Project


2. Task的依赖

一个Task又通过若干个Action组成。Gradle中原本的Task的执行顺序是不确定的,可以通过使用dependsOn指定Task的依赖顺序。

3. Task和增量构建

Gradle会缓存Task每次的运行结果,在下次运行时,检查输出结果有无变更,如果没有变更就回跳过这次运行。如果输入没有变化输出也不会发生变化。

ext命名空间

ext其实ExtensionAware的一个特殊属性

我们可以在顶级的build.gradle的同级目录下定义一个config.build,里面使用ext定义我们全局所需要的各种常量:

但是这个config.gradle,需要在build.gradle中apply:

这实际上调用的是PluginAware的方法:


于是我们可以在顶级的build.gradle和app模块的build.gradle中访问到:

我们可以使用Extension给一些可以配置的插件传值,如果不使用managed properties,我们也可以使用这样的形式:

这里不写getter和setter也是可以的

managed properties

Gradle能够允许用户声明一个属性为抽象的getter或者是一个抽象的属性,然后Gradle会自动提供这些属性的实现:https://docs.gradle.org/current/userguide/custom_gradle_types.html#managed_types

Mutable properties:

声明一个mutable managed property,需要给Property<T>提供一个抽象的getter。这里的T可以是任意的序列化类型或者是一个fully Gradle Managed type。对于这种属性,一定不可以声明任何的setter方法。这个东西有点像kotlin自动生成的getter和setter:

这里的@Input和@TaskAction注解都是一个mark的作用。TaskAction表示这个方法会被标记成一个action,在Task执行时被运行。

这里和上面直接写一个类然后设置值的方式好像没有本质上的不同,但是这里的getUri(getter)可以被转化成一个类似于Kotlin中的字段同时有了getter和setter的功能。

Read-only managed properties

使用只读的properties需要给Provider<T>加上getter方法,这个方法的实现中必须给出这个结果的推导方式:

Read-only managed nested properties
对于一个嵌套类型的传值。在这种情况下,用户不需要写任何的setter,因为Gradle会自动实现,并且Gradle会将值传给嵌套类型内部的properties。如果当前的property被声明为一个read-only managed nested property,这个property的getter 方法必须是抽象的并且public或者protected可见性,同时这个getter方法还需要被注解为@Nested:


但是这里我还有点没有搞明白,这个Resources应该如何传值呢?

Managed Types

managed type是一个抽象类,或者接口。这个类中没有任何字段,并且这个类中的所有属性都是被managed(应该是指通过Gradle生成的方法处理?)比如我们上面的Resources

Java bean Properties

使用Java Bean风格的Property,这种类型中没有Property<T>和Provider<T>,但是使用了实现了的getter 和 setter(常用的Java Bean中getter setter 都被手写写好了)。这种方式在Gradle中是不被提倡的。

Extension

通过Project获取ExtensionContainer,初始化新的Extension并且存入ExtensionContainer中。

类似于ext,可以直接通过project获取:

同样也可以使用managed properties:

NamedDomainObjectContainer

我们定义的buildTypes就是领域对象容器。通过指定不同的buildTypes的名称release 和debug可以设置不同的参数。这也是一个extension,所以内部的release和debug的配置是BuildType对象通过ExtensionContainer#create构建出来的





参考文章:

https://juejin.cn/post/6844903838290296846

https://www.jianshu.com/p/207c9f6f68c2






DEVLOG 9.22 Gradle 笔记(1)Gradle重要概念扫盲的评论 (共 条)

分享到微博请遵守国家法律