Android - 具有参数类型的顶级gradle任务:Exec在构建时自动运行,为什么?

时间:2015-12-18 01:39:24

标签: android gradle android-gradle gradlew

我有一个运行shell脚本的任务。它仅驻留在我的顶级gradle文件中。所以我在这里可以看到gradle文件:

enter image description here

现在对于有趣的部分,我在文件中有一个名为copyFiles的任务,它只运行一个简单的shell脚本来复制文件。我现在将向您展示我的整个build.gradle顶级文件:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.5.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

task copyFiles(type:Exec) {
    exec {
        commandLine 'sh', './copyFiles.sh'
    }
}

现在每当我构建项目时,此任务都会被执行。只要我构建项目(也就是编译它),这个任务就会运行。这是正常的吗?我在那里放了一条打印线,以确保每次构建'app'模块时都会运行。这是正常的吗?如果我不想那样做怎么办?

更新:现在研究后我发现一些gradle任务可以立即执行而不会被调用,如果这样定义:

//option 1, this runs right away on build
    task foo(type: Exec) {
    // this is configuration
    // i.e. it runs regardless
}
//option 2 this runs only when called on
  task bar(type: Exec) << {
    // this is execution
    // i.e. it only runs if you call the task
}

那么我想我会尝试同样的事情:

task copyFiles(type: Copy) {
    from '/Users/myuser/Documents/androidstudio/MyApplication/Common/'
    into '/Users/myuser/Documents/androidstudio/MyApplication/app/src/main/assets'
}

但令我惊讶的是它并没有自行运行。我实际上要打电话给它?这有什么不同然后输入:Exec?为什么没有一致性?

更新:

我为分析后需要帮助的人写了一篇关于the gradle lifecycle的博客。

1 个答案:

答案 0 :(得分:2)

您可能需要了解build lifecycle。运行构建时,此构建将经历3个阶段:初始化,配置和执行。

当您将闭包声明为:

task foo(type: Exec) {
    // this is configuration
    // i.e. it runs regardless
}

然后在配置阶段对所有任务执行此闭包,这就是为什么总是调用您的打印行,即使没有执行任务shell。它只是整个配置的一部分。

但是如果你用<<声明一个闭包,则为:

task bar(type: Exec) << {
    // this is execution
    // i.e. it only runs if you call the task
}

它在执行阶段执行。实际上,<<等于任务的doLast

此外,您在任务中使用exec {}表示法,在其中创建执行子任务。

因此,如果您不想在配置中运行它,那么只需将其与<<一起使用,或者不在任务中调用额外的exec任务,它本身就是Exec类型,只是正确配置它,如:

task copyFiles(type:Exec) {
   commandLine 'sh', './copyFiles.sh'
}