前言
本文主要梳理下如何开发自定义 Gradle 插件,参考自 Gradle 官网。
源码放置
一共有以下几个地方可以放置插件的源代码。
build script
在构建脚本中直接包含插件的源代码。这样做的好处是插件会自动编译并包含在构建脚本的类路径中,而您不需要做任何事情。然而,插件在构建脚本之外是不可见的,因此不能在定义插件的构建脚本之外重用插件。
buildSrc module
可以把插件的源代码放在rootProjectDir/buildSrc/src/main/java 目录下,注:如果用 groovy 写就把 java 替换为 groovy ,kotlin 也一样。Gradle 会自动进行编译,并使其在构建脚本的类路径中可用。该插件对构建所使用的每个构建脚本都是可见的。然而,它在构建之外是不可见的,因此不能在定义它的构建之外重用插件。插件 ID 通过 build.gradle 进行配置。
gradlePlugin {
plugins {
androidPackPlugin {
id = 'com.hefuwei.package'
implementationClass = 'com.hefuwei.pack.TestPlugin'
}
}
}standalone module
可以为你的插件创建一个单独的模块。该模块生成并发布一个 JAR,您可以在多个构建中使用该 JAR并与其他人共享。插件 ID 通过 properties 进行配置。
# com.android.application.properties 文件名就是插件 ID
com.android.build.gradle.AppPlugin =
在日常开发中 com.android.application、kotlin-android 等插件其实都是采用的第三种,因为前两种无法脱离当前项目,下面来看看如何编写插件。
插件编写
要开发一个 Gradle 插件,需要编写一个类实现 Plugin 接口,当插件被应用到一个项目时,Gradle 会创建一个该类实例,并调用其 apply 方法。下面以一个简单插件为例(代码直接放置 build.gradle 中),该插件逻辑非常简单就添加了一个名为 hello 的 Task。
class GreetingPlugin implements Plugin<Project> { |
配置好以后就可以在命令行中执行 gradle -q hello
,输出内容如下:
> gradle -q hello |
注意:Plugin 是一个泛型类,泛型类型除了 Project 以外,还可以是 Settings 以及 Gradle,其中前者可以在 settings.gradle 中被应用,后者可以在 init.gradle 中被应用,不过这两种使用场景还是比较罕见的。
插件配置
大多数插件都提供了配置项,比如 Android 构建插件 com.android.application 提供了以下配置项:
android { |
那么这个是如何做到的?其实很简单 Project 实例关联了一个 ExtensionContainer 实例,我们只需要写一个 JavaBean 类并添加到该容器中即可。下面为一个简单示例,其允许用户配置问候语。
class GreetingPluginExtension { |
配置好以后再次在命令行中执行 gradle -q hello
,输出内容如下:
> gradle -q hello |
插件扩展原理就是当 build.gradle 中使用了扩展名时 (本例中为 greeting )Gradle 就会创建扩展类(本例中未 GreetingPluginExtension)实例,然后执行闭包或者赋值操作。最后插件内部就可以获取到配置的内容(需要到项目配置完毕后才能取到值,因为插件应用阶段项目还没配置结束)。
插件发布
要发布插件那么只能把插件代码放到一个单独模块中去,然后在其 build.gradle 文件中应用 java-gradle-plugin 插件,这会应用 java 插件、添加 gradleApi 依赖以及自动生成 xxx.properties 文件(再也不用去记该把该文件放到哪里了)。同时还需要应用 maven 插件,添加 uploadArchives 这个 Task 其可以让我们把插件上传到 maven 仓库上去共享。
plugins { |
配置完毕后,直接执行 gradle {moduleName}: uploadArchives 即可上传到 maven 仓库。
应用远程插件
要想应用远程插件,首先得知道其在哪个仓库中,同时得了解其代码库名,以及插件 Id。配置项目级 build.gradle 文件配置插件仓库其代码库名。
buildscript { |
上述代码表示从 google 仓库中拉取 com.android.tools.build.gradle 代码库。同时在模块级 build.gradle 中应用指定插件。
plugins { |
完成上述配置后,Gradle 就会自动拉取代码库,并找到指定插件类并应用。