Gradle 和 Gradle 插件是两个概念,
Gradle 插件的本质就是抽取高度模块化的逻辑,以便更高效地进行复用。
Gradle 只是提供了一个构建流程。
而其他可复用的 Task(例如编译 Java 工程、编译 Android 工程等),
是通过应用 Gradle 插件来获取的。
Gradle: 构建工具,提供核心构建流程
Gradle 插件: 本质上是可复用的 task,依赖于 Gradle 环境
基础
gradle 插件比较主流的开发语言是 groovy
,因为 gradle 就是用 groovy 写的。
除了 groovy 还可以用来开发 gradle 插件的语言有:java
kotlin
其它基于 jvm 语言
因为 groovy 是基于 jvm 的,所以同样基于 jvm 的也可以用来写 gradle 插件。
但 java 和 kotlin 是静态语言,意味着需要不停地判断类型和强转,相比之下,groovy 作为动态语言就没有这个问题。
通常,使用 java 或 kotlin(静态类型)实现的插件比使用 groovy 实施的插件性能更好。
Gradle 基础 :Wrapper、Groovy、生命周期、Project、Task、增量
Gradle 插件:Plugin、Extension 扩展、NamedDomainObjectContainer、调试
官方文档: 其他BLOG Gradle Guides Developing Custom Gradle Plugins
Gradle插件
Gradle 插件的核心类是 Plugin,一般使用 Project 作为泛型实参。当使用方引入插件后,其实就是调用了 Plugin#apply() 方法,我们可以把 apply() 方法理解为插件的执行入口。例如:
1 | public class MyCustomGradlePlugin implements Plugin<Project> { |
Gradle 插件分为两大类:脚本插件 & 对象插件。
1、脚本插件
脚本插件和一个普通的 build.gradle 文件没什么区别,虽然简单,但它是模块化的基础。
脚本可以存在本地,也可以存在网络上,只需要提供脚本的相对路径或者 URL,例如:
在 build.gradle
配置 apply plugin: MyCustomGradlePlugin
或者 apply from: xxx.gradle
2、对象插件
对象插件 / 二进制插件: 在一个单独的插件模块中定义,其他模块通过 Plugin ID 应用插件。
因为这种方式发布和复用更加友好,我们一般接触到的 Gradle 插件都是指二进制插件的形式
编写一个对象插件的最低要求是提供一个 org.gradle.api.Plugin
接口的实现类,
这个接口只要一个Plugin#apply(Project)
方法。
应用插件
将插件添加到 classpath:
- 本地依赖: 指直接依赖本地插件源码,一般在调试插件的阶段是使用本地依赖的方式。
例如:根项目 build.gradle
1 | buildscript { |
- 远程依赖: 指依赖已发布到 Maven 仓库的插件,一般我们都是用这种方式依赖官方或第三方实现的 Gradle 插件。
例如:根项目 build.gradle
1 | buildscript { |
使用 apply 应用插件:
在 主项目 build.gradle 文件中,可以使用 apply 方法来应用插件,有两种语法:
1 | apply plugin: 'com.demo.MyCustomGradlePlugin' |
这里的 id
是插件的简短名称,是在插件中resources/META-INF/gradle-plugins/[id].properties
文件的文件名决定的。
注意: 在一个 build.gradle 中不要同时使用这两种语法。
自定义插件
自定义插件三种方式:
build script
:在build.gradle脚本中直接编写,只能在本文件内使用;
buildSrc项目
:新建一个名为buildSrc的Module,只能在本项目中使用;
独立的项目(standalone project)
:在独立的项目中编写插件,发布到本地或者远程maven仓库供其他项目使用。
- build script
- 在
app module
下的build.gradle
脚本文件编写插件。
1 | public class MyCustomGradlePlugin implements Plugin<Project> { |
- 在
根目录
下创建test.gralde
文件并添加脚本内容。
1 | public class MyCustomGradlePlugin implements Plugin<Project> { |
在app module
下的build.gradle
中添加apply from: '…/test.gradle’即可应用test.gralde脚本。
1 | apply from: '../test.gradle' |
- buildSrc 项目
在工程中新建buildSrc
目录,名称一定不能写错,在buildSrc目录下建立如下目录和文件:
1 | src/ |
编辑build.gradle文件,添加如下内容:
1 | apply plugin: 'kotlin' |
点击sync
或者buid project
(这一步必须),会生成build目录,groovy目录也会变成源文件目录,之后就可以创建包和源代码。
踩坑:
buildSrc 模块会被自动识别为参与构建的模块,因此不需要在 settings.gradle 中使用 include 引入,就算引入了也会编译出错.
buildSrc 模块会自动被添加到构建脚本的 classpath 中,不需要手动添加.
buildSrc 模块的 build.gradle 执行时机早于其他 Project.
- standalone project
新建一个module(新建一个工程也可以,因为最后生成和使用都是jar包的形式),
module名称随意,只保留build.gradle文件和src/main目录,其余文件全部删掉。
修改build.gradle文件内容,如下:
1 | apply plugin: 'maven' //要想发布到Maven,此插件必须使用 |
编写插件:
1 | public class MyCustomGradlePlugin implements Plugin<Project> { |
配置别名步骤:
在main
目录下新建resources/META-INF/gradle-plugins
目录,名称不能随意填写。
在gradle-plugins
下新建name(插件名).properties
文件,这个name
就是后面要使用的插件名。
例如:
1 | MyCustomGradlePlugin.properties //别人引用即可直接写 apply plugin: MyCustomGradlePlugin |
提示: 你可以通过 sourceSets {} 闭包方法来设置 resources 文件夹的位置。
发布:
在终端中执行./gradlew uploadArchives指令,或者展开Android Studio右侧的Gradle,
找到对应module->uploadArchivesTask,就可以将插件部署到相应的目录下。
插件调试
注意其中插图是引入他人的,不必较真,只是为了大家在UI上直观找到对应到自己项目中配置即可
-
方法 1(简单)
直接提供 Android Studio 中 Gradle 面板的调试功能,即可调试插件。如下图,我们选择与插件功能相关的 Task,并右键选择 Debug 执行。
-
方法 2(通过配置 IDE Configuration 以支持调试命令行任务)
1、创建 Remote 类型 Configuration:
2、执行命令: ./gradlew Task -Dorg.gradle.debug=true --no-daemon (开启 Debug & 不使用守护进程),执行后命令行会进入等待状态:
3、Attach Debug: 点击调试按钮,即可开始断点调试。
插件开发技巧
判断是否当前是 App 模块还是 Library 模块: 当我们开发 Android 项目相关插件时,经常需要根据插件的使用环境区分不同逻辑。
例如插件应用在 App 模块和 Library 模块会采用不同逻辑。此时,我们可以用在 Plugin#apply() 中采用以下判断:
1 | project.afterEvaluate { |
总结
开发gradle插件掌握方式三standalone project
就行了,关键是项目里面有相关的内容能看懂就行了。
其他比如字节码插桩、编译优化等高级开发都会涉及AGP的内容,参考链接: Gradle插件系列 调试Gradle插件 自定义Gradle插件 。