来自插件的Gradle任务不在“ Build”上运行,但在“ Clean”上运行

时间:2019-02-11 17:32:31

标签: android gradle android-gradle build.gradle gradle-plugin

我们有一个Android项目,需要在构建APK之前运行特定的Gradle插件任务。 (该插件由我们编写)

我们想在每次构建之前自动运行任务

如果我们使用已弃用的task.execute(),则会收到一条警告,指出从版本5.0或类似版本开始将不可用。

如果我们按照建议使用dependsOn,则testTask1不在BUILD之前,而仅在CLEAN之后。 (所有内容均在下面的评论中说明)

我已经遍历了gradle文档和许多其他SO线程,但是我还没有找到解决方案。

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {

    repositories {
        flatDir { dirs 'libs' }
        jcenter()
        google()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:3.1.3"

        // our platform-tools plugin, in charge of some gradle tasks
        classpath 'sofakingforevre:test-plugin:1.0-SNAPSHOT'
    }
}


apply plugin: 'test-plugin'


allprojects {
    repositories {
        jcenter()
        google()
    }
}

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


// OPTION 1 - USING EXECUTE()

// this task works as expected when calling "clean", but also when calling "assemble".
// the problem here is that the "execute" method has been deprecated, and we want to prepare for Gradle 5.0

// CLEAN - testTask1 is called :)
// BUILD - testTask1 is called :)
// DEPRECATION WARNING :(
task buildPlatformExecute {

    println("executing")

    // this task is created by the plugin
    tasks.getByName("testTask1").execute()


}

clean.dependsOn buildPlatformExecute

// OPTION 2 - USING DEPENDSON()

// this tasks works as expected when calling "clean", but DOES NOT WORK when calling "assemble".
// If we call we call assemble, the "executing" text does print, but "testTask1" would not run.

// CLEAN - testTask1 is called :)
// BUILD - testTask1 is NOT CALLED :(
task buildPlatformDependency {

    println("executing")

    // this task is created by the plugin
    dependsOn 'testTask1'
}

clean.dependsOn buildPlatformDependency

1 个答案:

答案 0 :(得分:2)

与您的 OPTION 1 解决方案有关

  • 您正在使用不推荐使用的task.execute() API(您已经知道了)
  • 您正在混合配置执行阶段(常见的Gradle错误...):

由于您没有在tasks.getByName("testTask1").execute()任务的doLast {}的{​​{1}}块的doFirst {}中包装buildPlatformExecute:无论您执行什么任务,都将始终执行testTask1任务将调用。您甚至不需要在clean任务和自定义任务之间创建依赖关系(例如:尝试使用./gradlew help执行简单的“帮助”任务,您将看到还执行了testTask1:当然不是您想要的)

更多信息在这里:https://docs.gradle.org/current/userguide/build_lifecycle.html

与您的 OPTION2 解决方案有关

您在clean任务和buildPlatformDependency任务之间创建了依赖项:

  • 执行clean任务时,testTask1任务将按预期执行,但是
  • build(或assemble)任务与clean任务之间没有依赖关系:这就是为什么当您执行build任务时,clean任务不是已执行(因此不会触发testTask1

解决方案

最好的方法是使用testTask1 API将自定义任务Task.dependsOn挂接到项目构建生命周期的正确位置。 “正确”的位置取决于您的任务在构建过程中负责什么:例如,如果您的任务需要在assemble任务之前执行,只需创建依赖项assemble.dependsOn testTask1