我正在嘗試按照Gradle 自定義插件檔案創建一個可以配置的插件。
我的插件代碼:
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>().myValue是null,所以set呼叫失敗。我該如何正確地做到這一點?我是否遺漏了檔案中的某些內容,還是只是錯誤?
uj5u.com熱心網友回復:
檔案沒有錯。屬性可以由您或 Gradle 管理。對于后者,必須滿足某些條件。
沒有托管屬性
如果你想完全掌控,你可以實體化你自己宣告的任何變數。例如,要在作為介面的擴展上宣告一個屬性,它可能如下所示:
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。
有關自己管理屬性的更多示例,請參見此處。
有托管屬性
為了幫助您減少樣板代碼,Gradle 可以使用所謂的托管屬性為您實體化屬性。要使用這些,屬性不能有 setter,并且 getter 應該是抽象的(它隱式地位于介面上)。所以你可以回到你的第一個例子并通過更改var為val:
interface MyExtension {
val myValue: Property<String> // val (getter only)
}
現在 Gradle 將為您實體化該欄位。同樣的事情適用于抽象類。
在此處的檔案中閱讀有關托管屬性的更多資訊。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/364741.html
標籤:科特林 等级 gradle插件 gradle-kotlin-dsl
上一篇:蒙特雷讓本地主機連接錯誤
