Plugin 的写法
最基本写法
写在 module#build.gradle 里,如下所示:
1 | //Plugin 的最基本写法 |
plugin 是可以进行配置的,在下面的 module#build.gradle 中:
1 | apply plugin: 'com.android.application' |
android 和 android 内部的一系列标签都是对 com.android.application 的配置。有的 plugin 不需要写配置也可以运行。如果需要动态配置,事实上可以写如下代码:
1 | class PluginDemo implements Plugin<Project> { |
但是和 com.android.application 的配置一样,我们需要变成类似下面的这种形式:
1 | xxx { |
Extension
如下代码所示,这样写就和 com.android.application 的配置样式一样了:
1 | //Plugin Extension |
由于代码是顺序执行的,当执行到 apply plugin: PluginDemo 时,void apply 内的方法会执行,如果不加 target.afterEvaluate 做延后执行,则打印出的是默认的“Author”。
如果只是按照上面的写法写 plugin,事实上是没有意义的,plugin 是为了重用。
写在 buildSrc 目录下
buildSrc 目录下的写法
目录结构如下图所示:
resources/META-INF/gradle-plugins/*.properties 中的 * 是插件的名称,例如
*.properties 是 com.wy521angel.plugindemo.properties,最终在应用插件时代码如下所示:
1 | apply plugin: 'com.wy521angel.plugindemo' |
*.properties 中只有一行,格式是:
1 | implementation-class=com.example.plugindemo.PluginDemo |
其中等号右边指定了 Plugin 具体是哪个类。Plugin 和 Extension 写法和在 build.gradle 里的写法一样。
关于 buildSrc 目录
- 这是 gradle 的一个特殊目录,这个目录的 build.gradle 会自动被执行,即使不配置进 settings.gradle;
- buildSrc 的执行早于任何一个 project,也早于 settings.gradle。它是一个独立的存在;
- buildSrc 所配置出来的 Plugin 会被自动添加到编译过程中的每一个 project 的 classpath,因此它们才可以直接使用 apply plugin: ‘xxx’的⽅方式来便捷应用这些 plugin;
- settings.gradle 中如果配置了’:buildSrc’,buildSrc 目录就会被当做是子 Project,因此会被执行两遍。所以在 settings.gradle 里面应该删掉 ‘:buildSrc’ 的配置。
Groovy 两个语法点
- getter / setter
每个 field,Groovy 会自动创建它的 getter 和 setter 方法,从外部可以直接调用,并且在使用 object.fieldA 来获取值或者使用 object.fieldA = newValue 来赋值的时候,实际上会
自动转而调用 object.getFieldA() 和 object.setFieldA(newValue)
这一点在 java 中是做不到的,groovy 和 java 可以相互调用,例如我们创建一个 JavaExtensionDemo,并在 PluginDemo 中使用
1 | def extension = target.extensions.create('wy', JavaExtensionDemo) |
运行会报错,提示“Could not find method name()”,因为 Java 并不会帮我们创建 getter 和 setter 方法。
Groovy 中下面有关 name 的三行是等效的:
1 | wy{ |
- 字符中的单双引号
单引号是不带转义的,而双引号内的内容可以使用 “string1${var}string2”的方式来转义。
Transform
Transform 是由 Android 提供了,在项目构建过程中把编译后的文件(jar 文件和 class 文件)添加自定义的中间处理过程的工具。
具体写法如下:
- 先加上依赖:
1 | // 因为 buildSrc 早于任何一个 project 执行,因此需要自己添加仓库 |
- 然后继承 com.android.build.api.transform.Transform ,创建一个子类:
1 | class TransFormDemo extends Transform { |
getInputTypes、getScopes 两个方法是需要配合使用的,例子中表示修改整个项目的字节码文件。transform 中的代码只是把编译完的内容原封不动搬运到目标位置,没有实际用处。要修改字节码,需要引入其它工具,例如 javassist。
- 注册 transform
代码如下所示:
1 | void apply(Project target) { |
bulid.gradle 里面的配制如下,代码必须要移到 android 标签之后,因为 PluginDemo2 增加了获取 android 标签配置类的功能。
1 | apply plugin: 'com.wy521angel.plugindemo2' |
参考资料:
腾讯课堂 HenCoder