许多Gradle功能都是通过添加插件(Plugin)来完成,例如插件可以添加新的任务(JavaCompile)、域对象(sourceSet)、约定(Java源码位于src/main/java文件下)等等功能。其实插件(Plugin)也可以分为两种常见的分类:脚本插件(Script Plugin)和二进制插件(Binary Plugin)。
二进制插件可以通过实现 Plugin 接口的方式编写,也可以通过 Groovy或 Kotlin DSL 中的声明来编写。它们可以驻留在构建脚本、项目层次结构中,也可以驻留在外部的插件 jar 中。脚本插件是附加的构建脚本,可进一步配置构建,并且通常实现声明性方法来操作构建。它们通常在构建中使用,但可以外部化和远程访问。
脚本插件(Script Plugin)
在Gradle的语境下,除去init.gradle(.kts)、build.gradle(.kts)和setting.gradle(.kts)脚本,其他脚本均视为插件,也就是脚本插件(Script Plugin)。这些脚本插件又可细分为两类:
- 独立脚本插件(
Standalone Script Plugin): 无特定的脚本存放点,只要是可被基础脚本索引到的独立脚本,都可称为独立脚本插件。 - 预编译脚本插件(
Precompiled Script Plugin): 需要将脚本放置到一个独立的模块,然后将其编译产物加入构建环境的依赖中,根据常见的存放点和引入方式,我们可以分为独立工程模块和buildSrc模块两种。
假设有这么一个需求:对Android的各个模块统一配置lint相关的参数。通过配置对比了解两种脚本的异同。
预编译脚本插件
首先看预编译脚本如何实现的,预编译脚本需要放入到独立的模块,为了方便放入到buildSrc内:
–Project
I—app
I—build.gradle.kts
I—buildSrc
I—src
I—main
I—kotlin
I—com.modi.introduction.buildSrc
I—lib-convention-script-plugin.gradle.kts
1 | plugins{ |
从上面看和我在模块中直接配置好像没什么区别,为什么放到buildSrc中的脚本就成了预编译脚本呢?
1 | plugins { |
实时上其中奥秘就是buildSrc模块下build.gradle.kts引入的kotlin-dsl插件:它引入了kotlin系列插件、Java-gradle-plugin、precompiled- script-plugin的系列插件,覆盖了Kotlin编译器插件和Gradle插件。脚本经过编译会生成一个普通的二进制插件,通过apply(...)方法包裹了其具体内容,预编译脚本插件的名称也由此而来:
1 | /** |
另外为了让独立脚本插件能够引用AGP配置,需要在
buildSrc的build.gralde.kts中引入相关依赖
独立脚本插件
接下来实现通过的功能看看独立脚本插件下如何配置
–Project
** I—app**
** I—build.gradle.kts**
** I—standalone-scripts**
** I—lib-convention-script-plugin2.gradle.kts**
1 | import com.android.build.gradle.LibraryExtension |