【问题标题】:Android - top level gradle task with parameter type:Exec runs automatically on build, why?Android - 具有参数类型的顶级 gradle 任务:Exec 在构建时自动运行,为什么?
【发布时间】:2015-12-18 01:39:23
【问题描述】:

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

现在有趣的部分是,我在名为 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'
    }
}

现在,每当我构建项目时,都会执行此任务。只要我构建项目(也就是编译它),这个任务就会运行。这正常吗?我在那里放了一条打印线以确保每次我构建“应用程序”模块时它都会运行。这正常吗。如果我不希望它那样做呢?

更新:现在经过研究,我发现如果定义如下,一些 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'
}

但令我惊讶的是,它不会自行运行。我居然要打电话?这与 type:Exec 有何不同?为什么没有一致性?

更新:

我写了一篇关于 the gradle lifecycle 的博客,供在我分析后需要帮助的人使用。

【问题讨论】:

    标签: android gradle android-gradle-plugin gradlew


    【解决方案1】:

    您可能需要阅读有关build lifecycle 的信息。当您运行构建时,此构建会经历 3 个阶段:初始化、配置和执行。

    当你声明一个闭包时:

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

    然后在配置阶段为所有任务执行此闭包,这就是为什么始终调用打印行的原因,即使未执行任务外壳也是如此。它只是整个配置的一部分。

    但是如果你用&lt;&lt;声明一个闭包,如下:

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

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

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

    所以,如果你不想在配置中运行它,那么只需将它与&lt;&lt; 一起使用,或者不要在任务中调用额外的exec 任务,它本身就是@ 类型987654330@ 并正确配置它,例如:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-24
      • 1970-01-01
      • 1970-01-01
      • 2015-12-28
      • 2018-08-19
      • 2015-11-13
      • 1970-01-01
      相关资源
      最近更新 更多