一文了解 Gradle 的服务

359 阅读3分钟

Gradle 提供了各种各样的服务,它们分别在构建中发挥各种各样的作用。我们也可以使用这些服务来实现我们的功能。各种服务的介绍如下:

ProjectLayout

ProjectLayout 在上一篇文章 一文了解 Gradle 的文件api 介绍过,作用是提供访问Gradle项目目录和文件布局的能力。通过这个服务,我们就不需要通过绝对路径来获取文件对象了。代码示例如下:

tasks.register("showLayout") {
    doLast {
        val layout = project.layout
        println("Project Directory: ${layout.projectDirectory}")
        println("Build Directory: ${layout.buildDirectory.get()}")
    }
}

BuildLayout

类似于 ProjectLayout,BuildLayout 服务提供了在 Settings 插件或脚本中提供访问根目录和设置目录的功能。代码示例如下:

println("Root Directory: ${settings.layout.rootDirectory}")
println("Settings Directory: ${settings.layout.settingsDirectory}")

ObjectFactory

用于创建自定义 Gradle 类型,提供创建多种类型对象的方法,如属性、集合、文件相关对象等,确保对象被Gradle正确管理,支持延迟获取来提升构建性能。

tasks.register("myObjectFactoryTask") {
    doLast {
        val objectFactory = project.objects
        val myProperty = objectFactory.property(String::class)
        myProperty.set("Hello, Gradle!")
        println(myProperty.get())
    }
}

ProviderFactory

用来创建不同类型 provider 对象。而 Provider 是用来延时初始化的,类似于kotlin 中的 by lazy。代码示例如下:

tasks.register("printMessage") {
    doLast {
        val providerFactory = project.providers
        val messageProvider = providerFactory.provider { "Hello, Gradle!" }
        println(messageProvider.get())
    }
}

WorkerExecutor

作用是执行异步的任务,适用于CPU密集型或长时间运行的任务,可提高构建性能,通过提交工作单元(WorkAction)到单独工作进程执行来隔离工作,提高可靠性。

代码示例如下,在MyWorkerTask任务中注入WorkerExecutor实例,提交MyWorkAction工作单元执行。

abstract class MyWorkAction : WorkAction<WorkParameters.None> {
    private val greeting: String = "Hello from a Worker!"

    override fun execute() {
        println(greeting)
    }
}

abstract class MyWorkerTask @Inject constructor(private var workerExecutor: WorkerExecutor) : DefaultTask() {
    @get:Input
    abstract val booleanFlag: Property<Boolean>
    @TaskAction
    fun doThings() {
        workerExecutor.noIsolation().submit(MyWorkAction::class.java) {}
    }
}

tasks.register("myWorkTask", MyWorkerTask::class) {}

在 Gradle 中注入服务有两种方式,一种是构造函数注入,一种是属性注入。代码示例如下:

// 构造函数注入
abstract class MyWorkerTask @Inject constructor(private var workerExecutor: WorkerExecutor) : DefaultTask() {

    ...
}

// 属性注入

abstract class MyWorkerTask: DefaultTask() {

    @get:Inject
    abstract val workerExecutor: WorkerExecutor

    ...

}

FileSystemOperations

用于提供执行文件系统操作的方法,如复制、删除、创建目录等,常用于自定义任务或插件与文件系统交互。代码示例如下:

// 在MyFileSystemOperationsTask任务中注入FileSystemOperations实例执行文件复制操作
abstract class MyFileSystemOperationsTask @Inject constructor(private var fileSystemOperations: FileSystemOperations) : DefaultTask() {

    @TaskAction
    fun doTaskAction() {
        fileSystemOperations.copy {
            from("src")
            into("dest")
        }
    }
}

tasks.register("myInjectedFileSystemOperationsTask", MyFileSystemOperationsTask::class) {}

ArchiveOperations

该服务提供了创建归档文件(如ZIP和TAR文件)的方法,常用于自定义任务或插件创建归档文件。代码示例如下:

// 通过 ArchiveOperations 来获取ZIP文件树
abstract class MyArchiveOperationsTask @Inject constructor(
    private val archiveOperations: ArchiveOperations,
    private val project: Project
) : DefaultTask() {

    @TaskAction
    fun doTaskAction() {
        archiveOperations.zipTree("${project.projectDir}/sources.jar")
    }
}

tasks.register("myInjectedArchiveOperationsTask", MyArchiveOperationsTask::class) {}

ExecOperations

提供在构建脚本中执行外部命令的方法,常用于自定义任务或插件运行命令行工具或脚本作为构建过程一部分。代码示例如下:

abstract class MyExecOperationsTask
@Inject constructor(private var execOperations: ExecOperations) : DefaultTask() {

    @TaskAction
    fun doTaskAction() {
        // 执行 `ls -la`命令
        execOperations.exec {
            commandLine("ls", "-la")
        }
    }
}

tasks.register("myInjectedExecOperationsTask", MyExecOperationsTask::class) {}

ToolingModelBuilderRegistry

用于注册自定义工具模型构建器,工具模型用于为Gradle项目提供丰富的IDE集成,使IDE能够理解和处理项目结构、依赖关系等。

参考