Appearance
自定义任务类
自定义任务类可以将可复用的构建逻辑封装为独立的类,支持类型安全的配置和增量构建。
基本自定义任务
在构建脚本中定义
kotlin
// build.gradle.kts
abstract class GreetTask : DefaultTask() {
@get:Input
abstract val greeting: Property<String>
@get:Input
abstract val name: Property<String>
@TaskAction
fun greet() {
println("${greeting.get()}, ${name.get()}!")
}
}
tasks.register<GreetTask>("greet") {
greeting = "Hello"
name = "Gradle"
}@Input / @Output 注解
注解是增量构建的基础,Gradle 通过它们追踪任务的输入和输出:
kotlin
abstract class GenerateTask : DefaultTask() {
// 输入:文件
@get:InputFile
abstract val templateFile: RegularFileProperty
// 输入:目录
@get:InputDirectory
abstract val sourceDir: DirectoryProperty
// 输入:属性值
@get:Input
abstract val packageName: Property<String>
// 输入:可选属性
@get:Input
@get:Optional
abstract val encoding: Property<String>
// 输出:文件
@get:OutputFile
abstract val outputFile: RegularFileProperty
// 输出:目录
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
@TaskAction
fun generate() {
val template = templateFile.get().asFile.readText()
val pkg = packageName.get()
val enc = encoding.getOrElse("UTF-8")
val output = template.replace("__PACKAGE__", pkg)
outputFile.get().asFile.writeText(output, charset(enc))
}
}
tasks.register<GenerateTask>("generateSources") {
templateFile.set(layout.projectDirectory.file("templates/MyClass.java.template"))
sourceDir.set(layout.projectDirectory.dir("src/main/java"))
packageName.set("com.example.generated")
outputFile.set(layout.buildDirectory.file("generated/MyClass.java"))
}常用注解
| 注解 | 说明 |
|---|---|
@Input | 输入属性(基本类型、String、枚举等) |
@InputFile | 输入文件 |
@InputFiles | 输入文件集合 |
@InputDirectory | 输入目录 |
@OutputFile | 输出文件 |
@OutputFiles | 输出文件集合 |
@OutputDirectory | 输出目录 |
@Optional | 可选(属性值可为 null) |
@Classpath | classpath(内容敏感) |
@Internal | 内部属性(不影响增量构建) |
@Destroys | 该任务会删除的文件 |
@LocalState | 本地状态文件(不参与缓存) |
在 buildSrc 中定义任务
将自定义任务放入 buildSrc 可以在所有子项目中共享:
buildSrc/
├── build.gradle.kts
└── src/main/kotlin/
└── com/example/gradle/
└── GenerateTask.ktkotlin
// buildSrc/src/main/kotlin/com/example/gradle/GenerateTask.kt
package com.example.gradle
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
abstract class GenerateTask : DefaultTask() {
@get:Input
abstract val className: Property<String>
@get:OutputFile
abstract val outputFile: RegularFileProperty
@TaskAction
fun generate() {
val code = "public class ${className.get()} {}"
outputFile.get().asFile.writeText(code)
}
}使用:
kotlin
// 任意子项目的 build.gradle.kts
import com.example.gradle.GenerateTask
tasks.register<GenerateTask>("generateModel") {
className.set("UserModel")
outputFile.set(layout.buildDirectory.file("generated/UserModel.java"))
}