如何用Kotlin DSL在Gradle约定插件中为Project添加自定义函数
解决Kotlin DSL约定插件添加Project动态方法的报错问题
方法1:直接定义Project扩展函数(最推荐)
Kotlin DSL是静态类型的,别沿用Groovy那套ext动态属性的思路,直接给Project类写扩展函数,编译器能直接识别并调用。
- 在
buildSrc/src/main/kotlin下编写插件类和扩展函数:
import org.gradle.api.Plugin import org.gradle.api.Project class SayHelloPlugin : Plugin<Project> { override fun apply(project: Project) { // 插件初始化逻辑可在此添加,扩展函数直接写在类外部即可 } } // 给Project类添加扩展函数,所有应用该插件的项目都能调用 fun Project.sayHello() { println("Hello from ${this.name}!") }
- 注册插件:在
buildSrc/src/main/resources/META-INF/gradle-plugins下创建com.example.sayhello.properties文件,内容如下:
implementation-class=com.example.SayHelloPlugin
- 在项目的
build.gradle.kts中应用插件并调用:
plugins { id("com.example.sayhello") } // 直接调用扩展函数,编译器可识别 sayHello()
方法2:通过ExtraPropertiesExtension注册函数(兼容Groovy风格)
如果一定要用extra存储函数,必须处理Kotlin的类型转换——因为extra存储的是Any?类型,调用时需显式转为函数类型:
- 插件类中注册函数:
import org.gradle.api.Plugin import org.gradle.api.Project class SayHelloPlugin : Plugin<Project> { override fun apply(project: Project) { // 将lambda函数存入extra属性 project.ext["sayHello"] = fun() { println("Hello from ${project.name}!") } } }
- 在项目
build.gradle.kts中调用:
plugins { id("com.example.sayhello") } // 从extra取出并转换为函数类型后调用 val sayHello = extra["sayHello"] as () -> Unit sayHello()
为啥之前的写法会报错?
- Kotlin是静态类型语言,不像Groovy支持动态方法调用,用
ext注册的函数不会被编译器识别为Project的成员函数,因此会报“未解析引用”“无法作为函数调用”。 by extra是用来实现属性委托的语法,不能用来注册函数,这么写自然无法生效。
内容的提问来源于stack exchange,提问作者René Link
相关产品推荐
相关产品推荐

