总的来说有5步:初始化插件目录结构、创建插件实现类、配置插件实现类、发布插件、使用插件
1. 初始化插件目录
根目录 -> New -> Module -> Java or Kotlin Library,然后修改 lib\build.gradle 文件
/*
timer
- customlib
- libs
- src
- .gitignore
- build.gradle
*/
// build.gradle
plugins{
// id 'java-library' 默认
id 'org.jetbrains.kotlin.jvm' // 默认,使用kotin语言开发必备
id 'groovy' // groovy 语言
id 'java-gradle-plugin' // 用于帮助开发gradle插件,会自动引用 'java-library'
}
dependencies {
implementation localGroovy()
implementation gradleApi()
}
sourceSets {
main {
groovy {
srcDir 'src/main/groovy'
}
resources {
srcDir 'src/main/resource'
}
}
}
java-gralde-plugin:用于帮助开发 gradle 插件,会自动应用 Java Library 插件,并在 dependencies 中添加 implementation gradleApi()
。如果 sync 中发现 but repository ‘Gradle Libs’ was added by unknown 错误,需要将 settings.gralde 中的 repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 注释
2. 创建插件实现类
// customlib\src\main\groovy\com.monk\customlib\CustomPlugin.groovy
class CustomPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
println 'Hello'
}
}
3. 配置插件实现类
// build.gradle
gradlePlugin {
plugins{
modularPlugin{
id = 'com.monk.customlib'
implementationClass = 'com.monk.customlib.CustomPlugin'
}
}
}
通过上述java gradle plugin
提供的一个简化的API,通过这个 API 会给我们创建一个 [插件ID].properties 文件 customlib\build\resources\main\META-INF\gradle-plugins\com.monk.customlib.properties
implementation-class=com.monk.customlib.CustomPlugin
/*
通过这种方式指定插件实现类的全限定类名
*/
4. 发布插件
使用 maven 插件来发布仓库
-
首先需要在根目录下的 build.gradle 下添加 github maven插件
// root -> build.gradle denpendencies{ // github maven 插件 classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' }
-
module 目录下的 build.gradle 添加 uploadArchives API
// module -> build.gradle plugins{ id 'com.github.dcendents.android-maven' // 引入 github-android-maven插件 } uploadArchives { repositories { mavenDeployer { repository(url: uri('../localMavenRepository/snapshot')) pom.groupId = 'com.monk.customlib' pom.artifactId = 'CustomPlugin' pom.version = '1.0.0' } } }
执行
uploadArchives
任务,会发布插件到项目根目录中的 localMavenRepository 目录下
5. 使用插件
-
在根目录 build.gradle 文件中将插件添加到 classpath
// root -> build.gradle buildscript{ repositories{ maven{url "$rootDir/localMavenRepository/snapshot"} maven{url "$rootDir/localMavenRepository/release"} } dependencies{ classpath 'com.monk.customlib:CustomPlugin:1.0.0' } }
-
在 app 中的 build.gradle 中 apply 插件
// gradlePlugin 中定义的插件 ID apply plugin: 'com.monk.customlib'
6. 插件扩展机制
相当于对外暴露的 Java Bean 或者 Groovy Bean,比如 android{}
就是 Android Gradle Plugin 提供的扩展,支持扩展名{}
DSL 的形式访问扩展对象;当应用一个插件时,插件定义的扩展会议 扩展名-扩展对象 键值对形式保存在 Project 中的 ExtensionContainer 中
-
定义扩展类
形象的以 android{} 举例,我们写个 bndroid{}进行理解,定义个扩展配置类:
// Bndroid.groovy class Bndroid{ String name }
-
创建并添加扩展对象
在 Plugin.apply() 方法中,将扩展对象添加到 Project 的 ExtensionContainer中:
// BndroidPlugin.groovy class BndroidPlugin implements Plugin<Project>{ @Override void apply(Project project){ // 创建扩展,并添加到 ExtensionContainer project.extensions.create("bndroid", Bndroid) // 添加 maven 发布 ... } }
-
配置扩展
使用方应用插件后,使用
扩展名{}
DSL 定制插件行为// app -> build.gradle plugins { ... id 'com.monk.customlib' } bndroid{ name = "monk" }
-
使用扩展
在 Plugin.apply 中,通过 Project 的 ExtensionContainer 获取扩展对象
// Bndroid.groovy class Bndroid{ String name static Bndroid getConfig(Project project){ ... } }
-
嵌套扩展
在扩展类中组合另一个配置类的情况,就叫做配置扩展,比如
defaultConfig{}
android { compileSdk 30 defaultConfig{ minSdk 21 } }
默认下的嵌套扩展时不支持使用闭包配置,我们需要在外部扩展定义闭包函数:
// Bndroid.groovy,伪代码如下 class Bndroid { // 嵌套扩展 Maven maven // 嵌套扩展闭包函数,方法名为 mavenPublish void mavenPublish(Action<Maven> action){ action.execute(maven) } // 嵌套扩展函数 void mavenPublish(Closure closure){ Utils.config(closure, maven) } }
使用时:
// app -> build.gradle plugins { ... id 'com.monk.customlib' } bndroid{ name = "monk" maven{ ... } }