gradle插件的开发方式 就目前知道有二种
1.直接在gradle文件内用groovy写,并直接引用
2.创建buildSrc目录单独编译再引用
实现原理上一样的,但是第二种更易于管理与发布,所以本文便以第二种方式来实践 文末为会附上第一种方式的实践代码
tips:基于
buildSrc下groovy的就不记录了,大同小异。着重记录使用kotlin来自定义插件
1.创建java or kotlin module 取名: buildSrc
只能叫这个名字,
buildSrc是gradle预留的插件开发目录 当然这只是android studio环境下的方式,其他方式参考官方文档即可 编译提示 'buildSrc' cannot be used as a project name as it is a reserved name 从settings.gradle里删除buildSrc重新编译就行,这毕竟是在android开发工具下,稍有水土不服
2.配置编译依赖
如果不用kotlin 可以忽略 使用groovy时除了java版本号以外其他均可删除 顺带一提代码位置在
src/main/kotlin与src/main/java都可以 不过只有一个有效,优先java目录
// 使用 plugins 块语法应用插件
plugins {
// 应用 kotlin 插件
id 'org.jetbrains.kotlin.jvm' version '1.3.72'
}
repositories {
google()
jcenter()
}
dependencies {
// 仅在编译时使用 Grdale-API 依赖
// compileOnly gradleApi() 目前暂时不知道gradleApi的作用 所以保持注释
// 在插件源码中添加 kotlin 标准库依赖
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
}
java {
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
}
3.创建插件
android studio IDE下,创建完buildSrc会自动生成一个插件类,但它没继承插件接口 需要稍微改改
class GrockPlugin :Plugin<Project> {
override fun apply(project: Project) {
println("GrockPlugin apply")
}
}
如果找不到Plugin这个接口,不要慌。依赖一下gradle就行 打开
buildSrc的build.gradle 添加依赖,gradle_version是项目根目录的gradle插件版本
dependencies {
implementation "com.android.tools.build:gradle:$gradle_version"
}
4.提供对外引用
按照文档要求整个声明文件即可 按如下目录创建一个
[外部引用时的插件名称].properties文件
|____main
| |____resources
| | |____META-INF
| | | |____gradle-plugins
| | | | |____com.grock.properties
如上此插件名为com.grock
打开[外部引用时的插件名称].properties文件,在其中指定插件类
implementation-class=com.grock.plugin.GrockPluginJava
5.引用插件
新建一个module 引用即可
apply plugin:'com.grock'
sync 查看日志
GrockPlugin apply
6.自定义一个拓展函数
为什么马不停蹄要先搞个拓展函数呢,基于目前的思考这东西能拿来当配置,所以优先尝试学习 类似于常见的android{}函数一样
6.1定义一个拓展函数类,不能是final的
open class GrockExtension {
var name= "GrockExtension original-name"
}
6.2创建一个拓展函数 grockName
override fun apply(project: Project) {
//创建拓展函数,拓展函数名称,拓展函数类
val extensionFun = project
.extensions.create("grockName",GrockExtension::class.java)
project.afterEvaluate {
println("GrockPlugin-kotlin afterEvaluate:${extensionFun.name}")
}
}
创建代码很好理解,最后两行的意义何在呢?为什么不直接打印呢? 原因非常简单,创建完拓展函数,插只是创建完这个拓展函数而在afterEvaluate回调时,插件已完成准备阶段,拓展函数都已读取,此时才能获取到拓展函数内的值
6.3使用拓展函数
apply plugin:'com.grock'
grockName{
name "newName"
}
打印内容:
GrockPlugin-kotlin afterEvaluate:newName
直接在gradle内用groovy自定义插件
插件代码:
class GrockPlugin implements Plugin<Project>{
@Override
void apply(Project target) {
println "GrokcPlugin apply"
// 创建拓展函数,声明拓展函数名 传入拓展类
def extension = target.extensions.create("nameFunction",GrockExtension)
target.afterEvaluate {//放在插件加完后执行,避免扩展函数未创建完成就访问
println " apply extension.name=${extension.name}"
}
}
}
class GrockExtension{
def name = "GrockExtension"
}
//从上到下逐个执行
apply plugin:GrockPluginJava
nameFunction {
name("extension-name") //setName("s")
}
插件引用:直接引用插件类
groovy语法上可以省略class
apply plugin:GrockPlugin
参考: