一、学习目标
- 1、 了解 Gradle Plugin 的作用是什么?
- 2、 如何去定义一个 Gradle Plugin?
- 3、 自定义插件扩展Extension。
一、Gradle Plugin 的作用是什么?
- 模块化构建脚本的功能
- 公共的功能可以抽取出来成为插件,可以供多个 build.gradle 使用,增加复用性。
二、定义一个 Gradle Plugin
2.1、插件的处理和应用
为了将构建脚本的逻辑封装到插件中,Gradle 需要做以下两件事:处理插件
,应用插件到目标中
。
- 处理插件
Gradle 会自动找到插件所在的位置,例如一个
buildSrc
名字 module 就会 Gradle 识别为插件工程。
- 应用插件
一旦插件被应用到执行的构建脚本中,那么插件对应的
apply(T target)
方法就会被调用。
2.2、 Gradle Plugin 创建
将插件定义在 buildSrc 中,这里的 buildSrc 就是当前工程下的一个 module ,Gradle 规定当一个module被命名为 buildSrc 时就会被当成插件去处理。
按照以下的步骤来创建一个简单的插件工程吧:
1、在当前工程下创建一个 Java Library 的 module,起名字为
buildSrc
-
2、将 main/src/java 修改为 main/src/groovy
3、创建类
PluginTest
实现 Plugin 接口并覆写 apply(T garget) 接口
Plugin<T> 是一个泛型接口,在定义插件是应该将这个泛型填为 Project 即可。
class PluginTest implements Plugin<Project> {
@Override
void apply(Project project) {
//定义一个 Task
project.task("MyTask") {
doLast {
println "MyTask doLast invoke..."
}
}
}
}
- 4、在外部应用这个插件
//在 app 下的 build.gradle 引用这个插件
apply plugin: PluginTest
- 5、验证效果
app module 引用了这个 PluginTest 插件,因此 app 这个 project 就有 MyTask 这个任务了,我们来执行一下验证一下效果吧。
./gradlew :app:MyTask
好了,通过上面几个步骤,就可以创建一个简单的 Gradle Plugin 工程了,但是回想一下,我们新建一个工程之后,在 build.gradle 中,Gradle 会帮我们引用 Android 插件apply plugin: 'com.android.application'
,它们引用方式就跟我们上面引用方式是不一样哦。
那这种引用方式是怎么定义的呢?
这里其实是给我们的 Plugin 起了个别名,然后在外部就是用这个别名来引用。接下来我们通过源码来看看'com.android.application'`是怎么定义的?
【举例】Gradle Android Plugin 中定义了一个叫 AppPlugin
的插件,这个插件是 Gradle 插件对 Android 的扩展,内部定义 Android 相关的一些东西,例如 我们所熟知 android{}
内部的东西都是属于 Gradle 插件对 Android 的扩展。详细的内容可以参考另一篇博客:从源码角度分析 Gradle 插件对 Android 的扩展
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.plugin"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
而这个 AppPlugin
就是 build.gradle
引入 apply plugin: 'com.android.application'
,查看源码,这个别名是定义在一个文件名
上的,文件内容对这个 AppPlugin 的映射关系。
那么我们依样画葫芦,我们也来定义一下我们插件的别名吧:
下面来看一下如何来声明我们自己的 Plugin ID 的
- 1、如下图所示在
src/main/resources/META-INF.gradle-plugins
文件夹下创建文件
因为插件类的包名为 com.example.buildsrc ,所以该文件明就是
包名.properties
- 2、文件内容
文件内容的 implementation-class 对应的值为
插件类的全限名称
。
implementation-class=com.example.buildsrc.PluginTest
- 3、引用插件
在 app 下的 build.gradle 引用这个插件
apply plugin:'com.example.buildsrc'
- 4、验证效果
app module 引用了这个 PluginTest 插件,因此 app 这个 project 就有 MyTask 这个任务了,我们来执行一下验证一下效果吧。
./gradlew :app:MyTask
好了,就这样,我们也可以像引用 Android Gradle Plugin ID 一样来引用我们自己的插件咯。
三、插件扩展 Extension
什么是扩展插件?
扩展插件 Extension 就是用于 Plugin 与 Project
通讯
用的。
【举例】我们想在 build.gradle 中通过配置 Extension 相关的属性 ,然后将 Extension 这个对象传递给我们自定义的 Plugin。
下面我们还是基于 PluginTest
这个插件来定义一个简单的插件扩展。
- 1、定义
TestExtension
类
我这里定义的是 Groovy Bean
(跟 Java Bean 类似),内部定义一个 message
变量。
class TestExtension {
String message;
}
- 2、 将 TestExtension 添加到 project#extensions 集合中。
class TestPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
//TestExtension extension = project.getExtensions().create("testExt", TestExtension)
//1.添加插件扩展到project.extensions集合中
project.extensions.add("testExt", TestExtension)
project.task("TestTask") {
doLast {
//2.获取外界配置的 TestExtension
TestExtension extension = project.testExt
//3.输出插件扩展属性
println ">>>>>>" + extension.message
}
}
}
}
- 3、 给插件扩展属性赋值
//build.gradle
//依赖我们定义的插件
apply plugin: 'com.example.plugin.extension'
testExt {
//给插件扩展的属性赋值
message "helloworld"
}
- 4、 测试验证
./gradlew :app:TestTask
> Task :app:TestTask
当前执行的 Task TestTask
>>>>>>helloworld
插件扩展在 Project 和 Plugin 之前传递数据如图所示
# 参考
记录于 2019年2月23日