How to get current buildType in Android Gradle con

2019-01-06 17:33发布

问题:

I want to dynamically add a dependency in an Android Gradle project based on the current buildType. I know I can specify the buildType in the dependency:

compile project(path: ':lib1', configuration: 'debug')

But how can I use the current buildType to specify which variant of the library I want to import, so that a debug or release build automatically imports the debug or release variant of the library? What I want is something like this (where currentBuildType is a variable containing the name of the currently used buildType):

compile project(path: ':lib1', configuration: currentBuildType)

The library project I want to import has set publishNonDefault true, so all buildTypes are published.

回答1:

Add a task which depends on each assembleXxx task and property setting up after it invoked

ext {
    currentConfig = ""
}
task generateConfigProperty(dependsOn: 'installDebug') {

    android.applicationVariants.all { variant ->
        variant.outputs.each { output ->

            def taskName = "taskindicate$output.name"
            task "$taskName"() << {
                project.ext.set("currentConfig", "$output.name")
            }
            output.assemble.dependsOn "taskindicate$output.name"
        }
    }

}

task getConfig(dependsOn: ['installDebug', 'generateConfigProperty']) << {
    println("My config is $currentConfig")
}

took idea from the answer



回答2:

I could not find a clean way to get the current build type during the configuration phase of Gradle. Instead I define the dependency for each build type separately like that:

debugCompile project(path: ':lib1', configuration: 'debug')
releaseCompile project(path: ':lib1', configuration: 'release')

If you have many build types and many project dependencies this can get very verbose, but it is possible to add a function to make the dependency a one-liner. You need to add this to your main Gradle build file:

subprojects {
    android {
        dependencies.metaClass.allCompile { dependency ->
            buildTypes.each { buildType ->
                "${buildType.name}Compile" project(path: ":${dependency.name}", configuration: buildType.name)
            }
        }
    }
}

Then you can add project dependencies in your Gradle modules like this:

allCompile project(':lib1')

If you also use build flavors you would have to adapt the solution. See this link for a documentation of the feature: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication

Please note that the Android team is working on an improvement for this behaviour: https://code.google.com/p/android/issues/detail?id=52962



回答3:

You can use

if(gradle.startParameter.taskNames.contains("assembleExample")) { // do stuff }

That variable will be set before the buildConfig block is evaluated



回答4:

This one is quite simple:

android {
    applicationVariants.all { variant ->
        variant.buildType.name // this is the value!
    }
}

Edit: Apparently at some point with gradle update, this is not working as I mentioned in a comment below. So I'd recommend checking other options.



回答5:

This is the easiest way to get the result you want. You define the global variable, then updated it for use later where ever needed.

// query git for the SHA, Tag and commit count. Use these to automate versioning.
def gitSha = 'git rev-parse --short HEAD'.execute([], project.rootDir).text.trim()
//def gitTag = 'git describe --tags'.execute([], project.rootDir).text.trim()
def gitCommitCount = 100 +
        Integer.parseInt('git rev-list --count HEAD'.execute([], project.rootDir).text.trim())
def buildTime = new Date().format("yyyy-MM-dd'T'HH:mm'Z'", TimeZone.getTimeZone("UTC"))

def versionMajor = 1
def versionMinor = 5
def versionPatch = 2
def versionBuild = 0 // bump for dogfood builds, public betas, etc.

def buildType // define here to update in loop

android {

    applicationVariants.all { variant ->
        buildType = variant.buildType.name // sets the current build type
    }

    defaultConfig {
        applicationId "com.example"
        minSdkVersion 19
        targetSdkVersion 25
        vectorDrawables.useSupportLibrary = true

        versionCode gitCommitCount
        versionName "${versionMajor}.${versionMinor}.${versionPatch}.${versionBuild}"
        versionNameSuffix "-${buildType}-build-${buildTime}"

}


回答6:

// declare a custom task class so you can reuse it for the different
// variants
class MyTask extends DefaultTask {
     String mVariantName;
     public void setVariantName(String variant) {mVariantName = variant;}
     public String getVariantName() { return mVariantName; }
     @TaskAction
     void action(){
        // do stuff
     }
}

// put this after your `android{}` block.
android.applicationVariants.all { variant ->
    def taskName = "myTask_$variant.name"
    task "$taskName"(type: MyTask) << {
        // you can setup this task to various info regarding
        // variant
        variantName = variant.name
    }
    variant.assemble.dependsOn (taskName)
}

See Advance customization for more details of what you can extract from the variant variable.

now you it will properly hookup your MyTask into to the chain. Doing it this way should also cleanly handle building multiple flavors all at once as it creates a new instance of MyTask for each variant.