在Android / Gradle中如何定义仅在构建特定buildType / buildVariant / productFlavor时运行的任务(v0.10 +)

时间:2014-03-30 11:54:08

标签: android gradle android-gradle

Gradle的Android插件为每个BuilType / Flavor / BuildVariant生成一项任务。问题是这个任务将动态生成,因此在定义这样的任务时不会作为依赖项提供:

task myTaskOnlyForDebugBuildType(dependsOn:assembleDebug) {
    //do smth
}

answer的建议解决方法是

task myTaskOnlyForDebugBuildType(dependsOn:"assembleDebug") {
    //do smth
}

或者

afterEvaluate {
    task myTaskOnlyForDebugBuildType(dependsOn:assembleDebug) {
        //do smth
    }
}

但两者都不适合我。

4 个答案:

答案 0 :(得分:40)

以下是有关如何执行此操作的完整示例inspired by this post (在撰写本文时,android插件v.0.9.2和gradle 1.11)

我们将定义一个仅在我们构建“debugCustomBuildType”时运行的任务

android {
    ...
    buildTypes {
        debugCustomBuildType {
            //config
        }
   }
}

定义只应在特定的builtType / variant / flavor

上执行的任务
task doSomethingOnWhenBuildDebugCustom {
    doLast {
       //task action
    }
}

通过gradle

添加任务时动态设置依赖关系
tasks.whenTaskAdded { task ->
    if (task.name == 'generateDebugCustomBuildTypeBuildConfig') {
        task.dependsOn doSomethingOnWhenBuildDebugCustom 
    }
}

这里我们使用“generateBuildConfig”任务,但您可以使用任何适合您的任务(also see official docs

  • processManifest
  • aidlCompile
  • renderscriptCompile
  • mergeResourcess。
  • mergeAssets
  • processResources
  • generateBuildConfig
  • javaCompile
  • processJavaResources
  • 组装

不要忘记使用buildTypeSpecific任务(generateBuildConfiggenerateDebugCustomBuildTypeBuildConfig

就是这样。遗憾的是,这种解决方法没有很好地记录,因为对我而言,这似乎是构建脚本最简单的要求之一。

答案 1 :(得分:7)

我实现了这样:

android {
    ext.addDependency = {
        task, flavor, dependency ->
            def taskName = task.name.toLowerCase(Locale.US)
            if (taskName.indexOf(flavor.toLowerCase(Locale.US)) >= 0) {
                task.dependsOn dependency
            }
    }

    productFlavors {
        production {
        }
        other
    }

    task theProductionTask << {
        println('only in production')
    }

    tasks.withType(JavaCompile) {
        compileTask -> addDependency compileTask, "production", theProductionTask
    }
}

坦率地说,我没有使用哪个语言环境为编译目标生成名称,因此toLowerCase(Locale.US)可能会适得其反。

答案 2 :(得分:2)

这是唯一对我有用的解决方案:

afterEvaluate {
    if (project.hasProperty("preReleaseBuild")){
        tasks.preReleaseBuild.dependsOn bundleJSRelease
    } else {
        tasks.preDebugBuild.dependsOn bundleJSDebug
    }
}

答案 3 :(得分:2)

tasks.whenTaskAdded { task ->
    if (task.name.contains("assembleRelease")) {
        task.getDependsOn().add({
            // add your logic here
        })
    }
}