前言

Android 插件其实是自定义的 Gradle 插件;Gradle 是一个专注于灵活性和性能的开源自动化构建工具,而插件的作用在于打包模块化的、可重用的构建逻辑;可以通过插件实现特定的逻辑,并打包起来分享给别人使用
Gradle概述
● Gradle是一个基于Ant和Maven概念的项目自动化构建工具;与Ant和Maven最大的不同之处在于,它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了传统的基于XML的各种烦琐配置
● Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具,支持maven、 Ivy仓库,支持传递性依赖管理,而不需要远程仓库或者是pom.xml和ivy.xml配置文件
● Gradle使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,目前也增加了基于Kotlin语言的kotlin-based DSL,抛弃了基于XML的各种繁琐配置
● 当前,Gradle其支持的语言有Java、Kotlin、Groovy 和 Scala,未来将支持更多的语言。在平时Android开发中,Android项目就是使用Gradle来构建的
代码示例
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n683" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.xzh.gradleplugin"
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}</pre>
Gradle 构建的生命周期
官方对于 Gradle 构建的生命周期的定义:Gradle 的核心是一种基于依赖的语言,用 Gradle 的术语来说这意味着你能够定义 Task 和 Task 之间的依赖关系。Gradle 会保证这些 Task 按照依赖关系的顺序执行并且每个 Task 只会被执行一次,这些 Task 根据依赖关系构成了一个有向无环图
Gradle 在执行任何 Task 之前都会用内部的构建工具去完成这样这样一个图,这就是 Gradle 的核心。这种设计使得很多原本不可能的事情成为可能
构建生命周期
根据Build phases 文档 和 Settings file 文档可以知道,Gradle 构建周期可以分为:初始化(Initialization)、配置(Configuration)和执行(Execution)
初始化(Initialization)
● Gradle可以构建一个和多个项目。在初始化阶段,Gradle会确定哪些项目参与构建,并且为这些项目创建一个Project实例
配置(Configuration)
● 在这个阶段,会配置project对象;将执行构建的所有项目的构建脚本。也就是说,会执行每个项目的build.gradle文件
执行(Execution)
● Gradle确定要在执行期间创建和配置的任务子集。子集由传递给gradle命令和当前目录的任务名称参数确定。 Gradle然后执行每个选定的任务
每次 Gradle 构建都需要经过三个不同的阶段:
● 初始化阶段:Gradle 是支持单项目和多项目构建的,因此在初始化阶段,Gradle 会根据 settings.gradle 确定需要参与构建的项目,并为每个项目创建一个 Project 实例。Android Studio 的项目和 Module 对 Gradle 来说都是项目;
● 配置阶段:在这个阶段会配置 Project 对象,并且所有项目的构建脚本都会被执行。例如:Extension 对象、Task 对象等都是在这个阶段被放到 Project 对象里;
● 执行阶段:经过了配置阶段,此时所有的 Task 对象都在 Project 对象中。然后,会根据终端命令指定的 Task 名字从 Project 对象中寻找对应的 Task 对象并执行。
Gradle 提供了很多生命周期的监听方法,用来在特定的阶段执行特定的任务。这里选取了部分回调方法,按照执行顺序关系画了一份 Gradle 生命周期流程简图

图中的生命周期回调方法里,属于 Project 有 project.beforeEvaluate 和 project.afterEvaluate,它们的触发时机分别是在 Project 进行配置前和配置结束后。在之前的示例中,正是使用了这里的 afterEvaluate,由于方法的最后一个参数是闭包所以写法优化成了 afterEvaluate{}。
使用 create 创建的对象,在对应 Project 还没配置完成的时候打印出来的值自然是不正确的,需要在配置完成后才能正确获取到写在 build.gradle 中的 Extension 值。因为直接写在 apply 方法里的逻辑是在配置阶段执行的,所以会出现这种情况
依赖管理
通常,一个项目的依赖会包含自己的依赖;例如,Spring 的核心需要几个其他包在类路径中存在才能运行;所以,当Gradle运行项目的测试,它也需要找到这些依赖关系,使它们存在于项目中
Gradle借鉴了Maven里面依赖管理很多的优点,甚至可以重用Maven中央库;你也可以将自己的项目上传到远程Maven库中;这也是Gradle能够成功的非常重要的原因一-站在巨人的肩膀之上,而非重复发明轮子
Gradle 设计介绍
Gradle 的扩展性十分强,它本身提供基本的概念和整体的核心框架,其他的具体场景逻辑,都是以插件的形式进行扩展
Gradle 本身就内置了很多常用插件,可以满足我们大部分的需求,但是也有一些常用的插件没有内置,这就需要我们自己去扩展实现,然后应用到 Gradle 当中去
Gradle的优势
● 更加的灵活,因为Gradle是编程框架,所以功能要强大的多
● 粒度性上,源码的编译,资源的编译,都是一个一个Task的,我们可以修改task来达到精细控制上
● 扩展性上,Gradle有插件机制
● 构建过程十分灵活,支持基于groovy语言编写脚本,侧重于构建过程的灵活性,适合于构建复杂度较高的项目,可以完成非常复杂的构建
● Gradle相比服务端java,在Android上更为流行,主要也是Android上更侧重构建的复杂性和多样性
● 构建效率高引入了build cache(构建缓存),官方数据显示Gradle比maven构建速度快2~10倍,这也是很多开源项目从maven迁移到gradle的重要原因
插件类型
Gradle 中有两种类型的插件:
● 脚本插件是一个额外的构建脚本,它提供了一种声明性方法来操作构建,通常在构建中使用
● 二进制插件是实现插件接口并采用编程方法来操作构建的类;二进制插件可以驻留在插件 JAR 中的一个构建脚本和项目层次结构或外部
Gradle 插件
Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,也增加了基于Kotlin语言的kotlin-based DSL,抛弃了基于XML的各种繁琐配置。
面向Java应用为主。当前其支持的语言C++、Java、Groovy、Kotlin、Scala和Swift,计划未来将支持更多的语言
Gradle是一个基于JVM的构建工具,是一款通用灵活的构建工具,支持maven, Ivy仓库,支持传递性依赖管理,而不需要远程仓库或者是pom.xml和ivy.xml配置文件,基于Groovy,build脚本使用Groovy编写
功能
● gradle对多工程的构建支持很出色,工程依赖是gradle的第一功能
● gradle支持局部构建
● 支持多方式依赖管理:包括从maven远程仓库、nexus私服、ivy仓库以及本地文件系统的jars或者dirs
● gradle是第一个构建集成工具,与ant、maven、ivy有良好的相容相关性
● 轻松迁移:gradle适用于任何结构的工程,你可以在同一个开发平台平行构建原工程和gradle工程。通常要求写相关测试,以保证开发的插件的相似性,这种迁移可以减少破坏性,尽可能的可靠。这也是重构的最佳实践
● gradle的整体设计是以作为一种语言为导向的,而非成为一个严格死板的框架
● 免费开源
gradle提供了什么
● 一种可切换的,像maven一样的基于约定的构建框架,却又从不锁住你(约定优于配置)
● 强大的支持多工程的构建
● 强大的依赖管理(基于Apache Ivy),提供最大的便利去构建你的工程
● 全力支持已有的Maven或者Ivy仓库基础建设
● 支持传递性依赖管理,在不需要远程仓库和pom.xml和ivy配置文件的前提下 ● 基于groovy脚本构建,其build脚本使用groovy语言编写
● 具有广泛的领域模型支持你的构建
应用 Android Gradle 插件
和应用 Java Gradle 插件不同的是,Android Gradle 是一个第三方插件,所以要配置它依赖的 classpath。在 AndroidStudio 中,新建工程后,在根工程的 build.gradle 中已经默认配置好了 Android Gradle 插件的仓库和 classpath
如图所示:

buildscript 这部分代码也可以在子项目的 build.gradle 文件,但是如果写在 根工程的 build.gradle 脚本中,每个子工程就不需要重复配置了
配置好 Android Gradle 插件后就可以使用了,在 Android Studio 中新建工程的默认子工程 app 已经添加了 APP 插件
如图所示

配置了 Android Gradle 插件的仓库,并且应用了一个 Android 的 app 插件
尾述
Gradle终将面向未来,就目前的趋势而言,Gradle正逐渐演化为一种标准;尤其是国际上,比如你去spring官网看demo,它们一般提供基于这种的源码,还有android开发,很多流行的库,demo演示都是通过gradle搭建的,你不懂gradle就很难跟它们接轨;这显然是固步自封的表现
技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面
Android 架构师之路还很漫长,与君共勉
PS:有问题欢迎指正,可以在评论区留下你的建议和感受; 欢迎大家点赞评论,觉得内容可以的话,可以转发分享一下
网友评论