Gradle's lifecycle consists of three main phases:
1. Initialization Phase
- Purpose: Determine which projects will participate in the build and create Project instances for each
- Execution:
- Read
settings.gradleorsettings.gradle.ktsfile - Determine project structure based on
includestatements - Create Project instances for each included project
- Execute
init.gradle(if present)
- Read
- Example:
groovy
// settings.gradle rootProject.name = 'my-project' include 'app', 'library', 'common'
2. Configuration Phase
- Purpose: Execute build scripts for all projects and build the task dependency graph
- Execution:
- Execute
build.gradleorbuild.gradle.ktsfor each project - Configure project properties, plugins, dependencies
- Create and configure all tasks
- Establish dependencies between tasks
- Execute
- Characteristics:
- All projects are configured even if only one task is executed
- Use
gradle -mor--dry-runto view tasks that will be executed
- Optimization Tips:
groovy
// Use onlyIf or enabled to skip unnecessary configuration tasks.register('myTask') { onlyIf { project.hasProperty('enableMyTask') } }
3. Execution Phase
- Purpose: Execute actual tasks according to the task dependency graph
- Execution:
- Only execute tasks specified on the command line and their dependencies
- Execute task action logic
- Support incremental builds, only process changed files
- Characteristics:
- Task execution order is determined by dependencies
- Support parallel execution (via
--parallelparameter) - Support continuous builds (via
--continuousparameter)
Lifecycle Hooks
Gradle provides multiple lifecycle hooks to execute custom logic at specific stages:
groovy// Initialization phase gradle.projectsLoaded { println "All projects loaded" } // Configuration phase gradle.beforeProject { project -> println "Configuring project: ${project.name}" } gradle.afterProject { project -> println "Project ${project.name} configuration complete" } // Execution phase gradle.taskGraph.whenReady { graph -> println "Task graph ready" } gradle.taskGraph.beforeTask { task -> println "About to execute task: ${task.name}" } gradle.taskGraph.afterTask { task, state -> println "Task ${task.name} completed, status: ${state.failure ? 'failed' : 'success'} }
Performance Optimization Recommendations
- Reduce work in configuration phase: Move unnecessary logic to execution phase
- Use lazy initialization: Use
tasks.register()instead oftasks.create() - Avoid I/O operations in configuration phase: Such as network requests, file reads/writes, etc.
- Use configuration cache: Enable via
--configuration-cacheparameter