android - 来自插件的 Gradle 任务不在 "Build"上运行,但在 "Clean"上运行

标签 android gradle android-gradle-plugin 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 解决方案存在问题

  • 您正在使用已弃用的 task.execute() API(您已经意识到这一点)
  • 您正在混合配置执行 阶段(一个常见的 Gradle 错误...):

由于您没有将 tasks.getByName("testTask1").execute() 包装在 doFirst {}doLast {}buildPlatformExecute 任务中的 block :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不会被触发)

解决方案

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

关于android - 来自插件的 Gradle 任务不在 "Build"上运行,但在 "Clean"上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54636048/

相关文章:

android - 某些设备不支持 SipApi

java - 如何使用 PowerMockRunner 模拟私有(private)或包保护类?

gradle - 没有更多关于 ':compileKotlin'的详细信息

java - 使用 XML 字符串

android - 如何使用 Amplify 从 Android 获取 AWS S3 中的对象 URL

gradle - gradle副本包括关闭不起作用

gradle - 为不同的构建类型设置不同的 versionName

android - 如何在库模块中添加 .aar 依赖项?

android-studio - 最好将 IntelliJ 项目转换为 Gradle 还是使用 Android Studio 导入项目?

java - Android Studio项目级build.gradle错误