在完成几个自定义 gradle 插件之后,我们发现 buildSrc 方式的开发效率是最高的,因为 buildSrc 是默认的插件目录,并且该目录与独立工程的插件目录一样,能够发布插件。该目录下的代码会在构建时自动进行编译打包,然后会被添加到 buildScript 中的 classpath 下,所以不需要其它配置,就可以被其它模块中的 gradle 脚本引用。
'buildSrc' cannot be used as a project name as it is a reserved name
错误/*
1. 新建 buildSrc module
2. 配置 groovy、resource 目录,去掉 java目录
timer
- buildSrc
- src
- main
- groovy
- resource
- .gitignore
- build.gradle
*/
// buildSrc\build.gradle
plugins {
id 'java-library'
id 'groovy' // groovy 语言
id 'java-gradle-plugin'
}
repositories {
google()
mavenCentral()
}
sourceSets {
main{
groovy{
srcDir 'src/main/groovy'
}
resources {
srcDir 'src/main/resource'
}
}
}
dependencies {
implementation localGroovy()
implementation gradleApi()
// 以下依赖需要在此 gralde 中配置 repositories
// Android DSL
implementation "com.android.tools.build:gradle:7.0.2"
// ASM V9.1
implementation 'org.ow2.asm:asm:9.1'
implementation 'org.ow2.asm:asm-commons:9.1'
}
我们再自定义一个 Plugin
// groovy\com\monk\customplugin\CustomPlugins.groovy
class CustomPlugins implements Plugin<Project> {
@Override
void apply(Project project) {
println "Hello Plugins ${project.name}"
}
}
在 resource 下先新建个层级目录META-INF\gradle-plugins
,然后在该目录下新建一个 [插件所在包名].properties 文件,文件内使用 implementation-class 标记插件(注:该做法可使用 gradlePlugin 方式自动实现,具体可参考customlib自定义插件方式)
// resource\META-INF\gradle-plugins\com.monk.customplugin.properties
implementation-class=com.monk.customplugin.CustomPlugins
最后在我们 app\build.gradle 下使用apply plugin: 'com.monk.customplugin'
,sync 后即可显示该插件的输出。如果已经存在 plugins{} 方式,apply plugin 必须置于 plugin{} 下边,才能避免编译出错
> Configure project :app
Hello Plugins app
自定义扩展属性,让使用插件这有配置插件的能力。首先定义一个属性类
// groovy\com.monk.customplugin.ReleaseInfoExt.groovy
class ReleaseInfoExt{
String versionName
String versionCode
String versionInfo
String fileName
}
接着在 Plugin 中进行声明
// groovy\com\monk\customplugin\CustomPlugins.groovy
class CustomPlugins implements Plugin<Project> {
@Override
void apply(Project project) {
println "Hello Plugins --buildSrc: ${project.name}"
// 创建用于设置版本信息的扩展属性
project.extensions.create("releaseInfo", ReleaseInfoExt.class)
}
}
app\build.gradle 下调用
apply plugin: 'com.monk.customplugin'
releaseInfo {
versionName = "v0.1.0"
versionCode = '1'
versionInfo = '发布了~~'
fileName = 'release.xml'
// 可以接着去定义实现逻辑
}
刚刚自定义 Extension,可以在相应的 extension 闭包下定义实现逻辑,但是我们也可以通过自定义 Task 的方式完成这部分的功能
// groovy\com\monk\customplugin\ReleaseInfoTask.groovy
class ReleaseInfoTask extends DefaultTask{
ReleaseInfoTask(){
group='version_manager'
description = 'release info update'
}
@Override
Task doFirst(Action<? super Task> action) {
println 'doFirst'
return super.doFirst(action)
}
@Override
Task doLast(Action<? super Task> action) {
println 'doLast'
return super.doLast(action)
}
@TaskAction
void doTask(){
// 可以接着去定义实现逻辑
}
// groovy\com\monk\customplugin\CustomPlugins.groovy
class CustomPlugins implements Plugin<Project> {
@Override
void apply(Project project) {
println "Hello Plugins --buildSrc: ${project.name}"
// 创建用于更新版本信息的 task
project.tasks.create("releaseInfoTask", ReleaseInfoTask.class)
}
}
但是经过验证,发现 buildSrc 下自定义 task 的方式,并未执行相关task,在app\build.gradle 下声明该 task 也会编译报错,所以还是再自定义 extension 中取定义实现逻辑吧