5月27日 23:20
What is a Task in Gradle? How to create and configure Tasks?
Tasks in Gradle are the basic execution units in the build process. Understanding the concept and configuration of Tasks is crucial for using Gradle efficiently.
Basic Concepts of Task
A Task is an atomic operation unit representing a specific step in the build process, such as compiling code, running tests, or packaging JAR files. Each Task has:
- Name: Uniquely identifies the task
- Type: Inherits from
org.gradle.api.Taskinterface - Action: The actual code that runs when the task executes
- Dependencies: Relationships with other tasks
- Inputs/Outputs: Input files and output files for incremental builds
Ways to Create Tasks
1. Using tasks.register() (Recommended)
groovy// Lazy initialization, created only when needed tasks.register('myTask') { doLast { println 'Executing myTask' } } // Specify task type tasks.register('copyFiles', Copy) { from 'src/main/resources' into 'build/resources' }
2. Using tasks.create() (Immediate Creation)
groovy// Create task instance immediately tasks.create('myTask') { doLast { println 'Executing myTask' } }
3. Direct Definition in build.gradle
groovytask myTask { doLast { println 'Executing myTask' } } task myTask2(type: Copy) { from 'src/main/resources' into 'build/resources' }
Task Configuration
Basic Configuration
groovytasks.register('myTask') { // Task description description = 'This is my custom task' // Task group group = 'Custom Tasks' // Set task dependencies dependsOn 'clean', 'compileJava' // Set task must run after mustRunAfter 'test' // Set task should run after shouldRunAfter 'build' // Set task inputs inputs.file('config.properties') inputs.dir('src/main/java') // Set task outputs outputs.dir('build/output') // Task actions doFirst { println 'Before task execution' } doLast { println 'After task execution' } }
Dynamic Configuration
groovy// Use configure block tasks.register('myTask') { doLast { println "Project name: ${project.name}" } } tasks.named('myTask').configure { enabled = project.hasProperty('enableMyTask') } // Batch configuration tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' options.compilerArgs << '-Xlint:unchecked' }
Task Dependencies
dependsOn
groovytasks.register('taskA') { doLast { println 'Task A' } } tasks.register('taskB') { dependsOn 'taskA' doLast { println 'Task B' } } // Multiple dependencies tasks.register('taskC') { dependsOn tasks.taskA, tasks.taskB doLast { println 'Task C' } }
mustRunAfter and shouldRunAfter
groovytasks.register('taskA') { doLast { println 'Task A' } } tasks.register('taskB') { doLast { println 'Task B' } } // taskB must run after taskA taskB.mustRunAfter taskA // taskC should run after taskA (soft constraint) tasks.register('taskC') { shouldRunAfter taskA doLast { println 'Task C' } }
finalizedBy
groovytasks.register('taskA') { finalizedBy 'cleanupTask' doLast { println 'Task A' } } tasks.register('cleanupTask') { doLast { println 'Cleanup' } }
Task Execution Control
Conditional Execution
groovytasks.register('conditionalTask') { onlyIf { project.hasProperty('runConditional') } doLast { println 'This task runs only if property exists' } } // Use enabled property tasks.register('anotherTask') { enabled = false // Disable task doLast { println 'This will not run' } }
Skip Execution
groovytasks.register('skipTask') { doLast { println 'This task will be skipped' } // Method 1: Use onlyIf onlyIf { false } // Method 2: Throw StopExecutionException doFirst { if (!project.hasProperty('force')) { throw new StopExecutionException() } } }
Common Built-in Task Types
- Copy: Copy files and directories
- Delete: Delete files and directories
- Exec: Execute external commands
- JavaExec: Execute Java applications
- Test: Run tests
- Jar: Create JAR files
- Zip/Tar/GZip: Create compressed files
Best Practices
- Use
tasks.register()instead oftasks.create(): Lazy initialization improves performance - Clearly define task inputs and outputs: Enable incremental builds to improve build speed
- Use task dependencies reasonably: Avoid circular dependencies
- Add descriptions and groups to tasks: Improve readability
- Use
doFirstanddoLast: Instead of writing code directly in the task body to avoid execution during configuration phase