15
votes

I have an Android app built with Gradle, which contains BuildTypes and Product Flavors (variants). I can for example run this command to build a specific apk:

./gradlew testFlavor1Debug
./gradlew testFlavor2Debug

I have to create a custom task in the build.gradle per variant, for example:

./gradlew myCustomTaskFlavor1Debug

I have created a task for this:

android.applicationVariants.all { variant ->
    task ("myCustomTask${variant.name.capitalize()}") {
        println "*** TEST ***"
        println variant.name.capitalize()
    }
}

My problem is that this task is called for ALL the variants, not the only one I am running. Output:

./gradlew myCustomTaskFlavor1Debug

*** TEST ***
Flavor1Debug
*** TEST ***
Flavor1Release
*** TEST ***
Flavor2Debug
*** TEST ***
Flavor2Release

Expected output:

./gradlew myCustomTaskFlavor1Debug

*** TEST ***
Flavor1Debug

How can I define a custom task, dynamic, per variant, and then call it with the right variant?

2

2 Answers

18
votes

It happens because the logic is executed at configuration time. Try adding an action (<<):

android.applicationVariants.all { variant ->
    task ("myCustomTask${variant.name.capitalize()}") << {
        println "*** TEST ***"
        println variant.name.capitalize()
    }
}
3
votes

Following Opal's answer and the deprecation of << operator since Gradle 3.2, the correct answer should be:

android.applicationVariants.all { variant ->
    task ("myCustomTask${variant.name.capitalize()}") {
        // This code runs at configuration time

        // You can for instance set the description of the defined task
        description = "Custom task for variant ${variant.name}"

        // This will set the `doLast` action for the task..
        doLast {
            // ..and so this code will run at task execution time
            println "*** TEST ***"
            println variant.name.capitalize()
        }
    }
}