了解在 Gradle 中声明任务的不同变体
Understanding different variants of declaring a task in Gradle
在 Gradle 中声明任务有两种不同的变体。
1.
task myTask() {}
2.
task task3 << {}
为了测试它们的行为方式,我创建了一个示例 android 项目
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.android.gradletest"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
}
task task1() {
println "Task 1"
}
task task2() {
println "Task 2"
}
task task3 << {
println "Task 3"
}
task task4() {
println "Task 4"
}
第一次尝试正在执行任务 1
Task 1
Task 2
Task 4
:app:task1 UP-TO-DATE
BUILD SUCCESSFUL
Total time: 6.462 secs
Process finished with exit code 0
如您所见,不仅执行了任务 1,还执行了没有任务 3 的完整构建。
第二次尝试 运行直接任务 3:
Task 1
Task 2
Task 4
:app:task3
Task 3
BUILD SUCCESSFUL
Total time: 6.577 secs
Process finished with exit code 0
结果又是,似乎触发了完整的构建,但这次是 WITH Task 3 最后。
第三次尝试 只是通过按下 Android Studio
的 运行 按钮来构建完整的项目
Task 1
Task 2
Task 4
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:preReleaseBuild UP-TO-DATE
:app:prepareComAndroidSupportAppcompatV72211Library UP-TO-DATE
:app:prepareComAndroidSupportSupportV42211Library UP-TO-DATE
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:processDebugJavaRes UP-TO-DATE
:app:compileDebugJava
Note: Recompile with -Xlint:deprecation for details.
:app:compileDebugNdk UP-TO-DATE
:app:compileDebugSources
:app:preDexDebug
:app:dexDebug
:app:validateDebugSigning
:app:packageDebug
:app:zipalignDebug
:app:assembleDebug
Information:BUILD SUCCESSFUL
如您所见,除任务 3 外,所有内容都已触发!
现在我有两个问题:
- 当我们无法运行它独立并且不在构建过程中触发时,<< 任务声明有什么用?
- 为什么我从任务菜单中只执行一个任务时会触发多个任务,那么我如何只执行一个任务?
Gradle 构建经历 3 个阶段:
- 初始化 - 确定哪些项目将参与构建,并为每个项目创建一个项目实例。
- 配置 - 配置项目对象,特别是要执行的任务。
- 执行 - 执行在配置阶段创建和配置的任务子集。
现在,任务定义包含 3 个阶段:
task myTask {
// Configuration scope
// will be executed during the configuration phase
doFirst {
// Will be executed during the execution phase before the task defined behavior
}
doLast {
// Will be executed during the execution phase after the task defined behavior
}
}
因此,当您定义这样的任务时:
task task1() {
println "Task 1"
}
由于 println
语句是配置范围的一部分,它将在配置阶段执行,无论是否选择执行此任务。
现在,使用 <<
运算符来定义任务实际上是为任务定义 doLast
闭包的快捷方式,即
task task3 << {
println "Task 3"
}
相当于:
task task3 {
doLast {
println "Task 3"
}
}
然后,根据我上面的解释,在这种情况下,println
语句将仅在执行阶段执行,以防 task3
必须按照配置阶段确定的那样执行。
如果您有兴趣了解更多信息,我强烈建议您阅读 Gradle 用户指南中的以下部分:
在 Gradle 中声明任务有两种不同的变体。
1.
task myTask() {}
2.
task task3 << {}
为了测试它们的行为方式,我创建了一个示例 android 项目
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.android.gradletest"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
}
task task1() {
println "Task 1"
}
task task2() {
println "Task 2"
}
task task3 << {
println "Task 3"
}
task task4() {
println "Task 4"
}
第一次尝试正在执行任务 1
Task 1
Task 2
Task 4
:app:task1 UP-TO-DATE
BUILD SUCCESSFUL
Total time: 6.462 secs
Process finished with exit code 0
如您所见,不仅执行了任务 1,还执行了没有任务 3 的完整构建。
第二次尝试 运行直接任务 3:
Task 1
Task 2
Task 4
:app:task3
Task 3
BUILD SUCCESSFUL
Total time: 6.577 secs
Process finished with exit code 0
结果又是,似乎触发了完整的构建,但这次是 WITH Task 3 最后。
第三次尝试 只是通过按下 Android Studio
的 运行 按钮来构建完整的项目Task 1
Task 2
Task 4
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:preReleaseBuild UP-TO-DATE
:app:prepareComAndroidSupportAppcompatV72211Library UP-TO-DATE
:app:prepareComAndroidSupportSupportV42211Library UP-TO-DATE
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:processDebugJavaRes UP-TO-DATE
:app:compileDebugJava
Note: Recompile with -Xlint:deprecation for details.
:app:compileDebugNdk UP-TO-DATE
:app:compileDebugSources
:app:preDexDebug
:app:dexDebug
:app:validateDebugSigning
:app:packageDebug
:app:zipalignDebug
:app:assembleDebug
Information:BUILD SUCCESSFUL
如您所见,除任务 3 外,所有内容都已触发!
现在我有两个问题:
- 当我们无法运行它独立并且不在构建过程中触发时,<< 任务声明有什么用?
- 为什么我从任务菜单中只执行一个任务时会触发多个任务,那么我如何只执行一个任务?
Gradle 构建经历 3 个阶段:
- 初始化 - 确定哪些项目将参与构建,并为每个项目创建一个项目实例。
- 配置 - 配置项目对象,特别是要执行的任务。
- 执行 - 执行在配置阶段创建和配置的任务子集。
现在,任务定义包含 3 个阶段:
task myTask {
// Configuration scope
// will be executed during the configuration phase
doFirst {
// Will be executed during the execution phase before the task defined behavior
}
doLast {
// Will be executed during the execution phase after the task defined behavior
}
}
因此,当您定义这样的任务时:
task task1() {
println "Task 1"
}
由于 println
语句是配置范围的一部分,它将在配置阶段执行,无论是否选择执行此任务。
现在,使用 <<
运算符来定义任务实际上是为任务定义 doLast
闭包的快捷方式,即
task task3 << {
println "Task 3"
}
相当于:
task task3 {
doLast {
println "Task 3"
}
}
然后,根据我上面的解释,在这种情况下,println
语句将仅在执行阶段执行,以防 task3
必须按照配置阶段确定的那样执行。
如果您有兴趣了解更多信息,我强烈建议您阅读 Gradle 用户指南中的以下部分: