Appearance
Provider API
Provider API 是 Gradle 5+ 引入的核心 API,提供类型安全的懒加载值管理。
核心接口
Provider<T> ← 只读的懒加载值
├── Property<T> ← 可写的 Provider
│ ├── RegularFileProperty ← 文件属性
│ ├── DirectoryProperty ← 目录属性
│ └── ConfigurableFileCollection ← 文件集合
└── ProviderFactory ← 创建各种 Provider 的工厂创建 Provider
kotlin
// 通过 project.providers 创建
val stringProvider: Provider<String> = providers.provider { "Hello" }
val fileProvider = providers.fileContents(layout.projectDirectory.file("version.txt")).asText
val envProvider = providers.environmentVariable("ENV_VAR")
val propProvider = providers.gradleProperty("myProp")
// 通过 layout 创建文件 Provider
val buildFile = layout.buildDirectory.file("output.jar")
val buildDir = layout.buildDirectory.dir("reports")
// 通过 ObjectFactory 创建
abstract class MyTask @Inject constructor(objects: ObjectFactory) : DefaultTask() {
val myProp: Property<String> = objects.property(String::class.java)
val myFile: RegularFileProperty = objects.fileProperty()
}转换 Provider
kotlin
val version: Provider<String> = providers.gradleProperty("version")
// map:转换类型
val majorVersion: Provider<Int> = version.map { it.split(".")[0].toInt() }
// flatMap:Provider<Provider<T>> → Provider<T>
val resolvedVersion = version.flatMap { v ->
providers.provider { lookupVersion(v) }
}
// zip:合并两个 Provider
val appId: Provider<String> = group.zip(version) { g, v -> "$g:$v" }
// orElse:提供默认值
val safeVersion = version.orElse("0.0.0-SNAPSHOT")
// filter:条件过滤(不满足则 Provider 无值)
val releaseVersion = version.filter { !it.endsWith("SNAPSHOT") }在自定义任务中使用
kotlin
abstract class GenerateReportTask : DefaultTask() {
@get:Input
abstract val reportTitle: Property<String>
@get:InputDirectory
abstract val sourceDir: DirectoryProperty
@get:OutputFile
abstract val reportFile: RegularFileProperty
@TaskAction
fun generate() {
val title = reportTitle.get()
val src = sourceDir.get().asFile
val out = reportFile.get().asFile
out.writeText("# $title\n\nSource: ${src.path}")
}
}
tasks.register<GenerateReportTask>("generateReport") {
reportTitle.set("My Report")
reportTitle.set(providers.gradleProperty("reportTitle").orElse("Default Report"))
sourceDir.set(layout.projectDirectory.dir("src"))
reportFile.set(layout.buildDirectory.file("reports/report.md"))
}Provider 链式配置(推荐模式)
kotlin
// 避免配置阶段的副作用
tasks.named<Jar>("jar") {
// 懒加载:只在 jar 任务执行时计算版本
archiveVersion.set(providers.gradleProperty("version").orElse("0.0.0"))
// 懒加载:从文件读取
archiveBaseName.set(
providers.fileContents(layout.projectDirectory.file(".appname"))
.asText
.map { it.trim() }
.orElse(project.name)
)
}下一步
- Worker API - 任务内并行
- Toolchain - JDK 工具链