在Gradle Kotlin DSL中注册和创建之间有什么区别

mad*_*ead 6 gradle kotlin gradle-kotlin-dsl

在Gradle(5.0+)中有两种创建方法,即任务:

tasks {
    val javadocJar by creating(Jar::class) {
        val javadoc by tasks

        from(javadoc)
        classifier = "javadoc"
    }
}
Run Code Online (Sandbox Code Playgroud)

tasks {
    val javadocJar by registering(Jar::class) {
        val javadoc by tasks

        from(javadoc)
        classifier = "javadoc"
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上是相同的API,有什么区别?

M.R*_*uti 7

参见https://docs.gradle.org/current/userguide/kotlin_dsl.html#using_the_container_api

tasks.named("check")                  
tasks.register("myTask1")
Run Code Online (Sandbox Code Playgroud)

上面的示例依赖于配置避免API。如果您需要或希望热切地配置或注册容器元素,只需将named()替换为getByName()并将register()替换为create()。

之间的区别creatingregistering(或createregister在摇篮之前的版本5.0)是关系到Task Configuration Avoidance新的API,这是在细节exaplined 这里(见本节:)

如何推迟任务创建?

该功能要求构建作者选择加入,方法是将任务创建从TaskContainer.create(java.lang.String)API迁移到TaskContainer.register(java.lang.String)API。register(…?)API仅在需要时才注册要在以后创建的任务。当调用create(…?)API时,它会继续急切地创建和配置任务。

  • 总之,“注册效率更高,并且将推迟创建和配置直到需要为止”。此处参考:https://github.com/gradle/gradle/blob/master/subprojects/core-api/src/main/java/org/gradle/api/NamedDomainObjectContainer.java#L88 (17认同)

mad*_*ead 6

接受的答案很好,但我想补充一点,如果您想稍后实际使用created/ registeringcall创建的引用,那么 API 将有所不同。相比

create<MavenPublication>("main") {
    …

    val sourcesJar by tasks.creating(Jar::class) {
        val sourceSets: SourceSetContainer by project
        from(sourceSets["main"].allJava)
        classifier = "sources"
    }

    artifact(sourcesJar)
}
Run Code Online (Sandbox Code Playgroud)

create<MavenPublication>("main") {
    …

    val sourcesJar by tasks.registering(Jar::class) {
        val sourceSets: SourceSetContainer by project
        from(sourceSets["main"].allJava)
        classifier = "sources"
    }

    artifact(sourcesJar.get())
}
Run Code Online (Sandbox Code Playgroud)

在注册的情况下,因为它是懒惰的,你需要额外的.get()调用,否则你会得到一个异常:

* What went wrong:
Cannot convert the provided notation to an object of type MavenArtifact: task ':experiments:sourcesJar'.
The following types/formats are supported:
  - Instances of MavenArtifact.
  - Instances of AbstractArchiveTask, for example jar.
  - Instances of PublishArtifact
  - Maps containing a 'source' entry, for example [source: '/path/to/file', extension: 'zip'].
  - Anything that can be converted to a file, as per Project.file()
Run Code Online (Sandbox Code Playgroud)

  • 这是因为 `artifact(..)` 不支持惰性配置 API,您可以在 https://github.com/gradle/gradle/issues 提交错误吗? (2认同)