kotlin - 使用自定义插件时 Gradle 提供的 Null 属性

标签 kotlin gradle gradle-plugin gradle-kotlin-dsl

我正在尝试遵循 Gradle custom plugin documentation创建一个可以配置的插件。

我的插件代码:

interface MyExtension {
    var myValue: Property<String>
}

class MyPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        val extension = project.extensions.create<MyExtension>("myExt")
    }
}

build.gradle.kts :

plugins {
    `java-library`
}

apply<MyPlugin>()
the<MyExtension>().myValue.set("some-value")

运行这个将会给出

Build file '<snip>/build.gradle.kts' line: 6
java.lang.NullPointerException (no error message)

结果是the<MyExtension>().myValuenull ,所以set调用失败。我该如何正确地做到这一点?我是否遗漏了文档中的某些内容,或者只是错误的?

最佳答案

文档没有错误。属性可以由您或 Gradle 管理。对于后者,必须满足一定的条件。

没有托管属性

如果您想完全掌控,您可以实例化您自己声明的任何变量。例如,要在作为接口(interface)的扩展上声明属性,它可能如下所示:

override fun apply(project: Project) {
  val extension = project.extensions.create("myExt", MyExtension::class.java)
  extension.myValue = project.objects.property(String::class.java)
}

或者您可以通过将其设为类来直接在扩展中实例化它:

open class MessageExtension(objects: ObjectFactory) {
  val myValue: Property<String> = objects.property(String::class.java)
}

但是,属性字段实际上并不应该具有 setter,因为属性本​​身同时具有 setter 和 getter。因此,您通常应该避免第一种方法并删除第二种方法的 setter 。

参见here有关自行管理特性的更多示例。

具有托管属性

为了帮助您减少样板代码,Gradle 可以使用所谓的“托管属性”为您实例化属性。要使用它们,属性必须没有有setter,并且getter应该是抽象的(它隐式地位于接口(interface)上)。因此,您可以返回第一个示例并通过将 var 更改为 val 来修复它:

interface MyExtension {
    val myValue: Property<String> // val (getter only)
}

现在 Gradle 将为您实例化该字段。同样的事情也适用于抽象类。

在文档 here 中了解有关托管属性的更多信息.

关于kotlin - 使用自定义插件时 Gradle 提供的 Null 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70064307/

相关文章:

gradle - 如何使用格拉德脚本在 war 构建中添加WEB-INF/lib jar

gradle - 设置多项目 Gradle 构建

java - Android Studio 1.4 - 在根项目 'assemble' 中找不到任务 'bin'

java - 在 IntelliJ 中设置 Gradle 任务 `bootrun`

kotlin - 我可以在 Kotlin 中使用 Dagger 2 的场注入(inject)吗?

java - 想要使用 StringBuilder 添加带有 TextView 数字的上标

java - Dagger /缺失绑定(bind)。如果没有 @Provides 注释的方法,则无法提供输出器

android - 使用 Kotlin : ClassNotFoundException 创建 AAR

android - Android Studio 版本与使用的 Gradle 插件不兼容

Gradle 发布带有发布顺序的复合构建