gradleandroid-build-flavorsandroid-buildconfigandroid-flavordimension

Combined BuildConfig variables in gradle flavor dimensions


In my Android application I have two flavor dimensions: "brand" (brand1, brand2) and "environment" (staging, production). I added the "environment" dimension after a while and I had previously defined some BuildConfig variables for the different brands. To be more specific, I defined the BASE_URL like this:

flavorDimensions 'brand'
productFlavors {

    brand1 {
        dimension 'brand'
        ...
        buildConfigField "String", "BASE_URL", "\"http://brand.one.api/\""
        ...
    }

    brand2 {
        dimension 'brand'
        ...
        buildConfigField "String", "BASE_URL", "\"http://brand.two.api/\""
        ...
    }
}

Now, I added the "environment" dimension and what I'd like to set are four different endpoints:

  1. Brand1-staging: "http://brand.one.staging.api/"
  2. Brand1-production: "http://brand.one.production.api/"
  3. Brand2-staging: "http://brand.two.staging.api/"
  4. Brand2-production: "http://brand.two.production.api/"

But I can't figure out how to create a BuildConfig variable for a specific combination of flavor dimensions. Is this even possible with bare gradle?

Thanks


Solution

  • After some further investigation I found a similar question here.

    It seems you need to add a function to iterate build variant names and check if they match some desired name.

    My problem was that actually I had 3 dimensions: "brand", "environment" and "api" (15 for production and 21 for debugging with instant run). So the variants name would look like brand1Api15StagingDebug, ..., brand2Api21ProductionRelease, ... etc.

    What I needed here was some groovy regex matching combined with the linked question above. Finally the function I made looks like this:

    android.applicationVariants.all { variant ->
        if (variant.getName() ==~ /brand1Api[0-9]{2}Staging.*/) {
            variant.buildConfigField "String", "BASE_URL", "\"http://brand.one.staging.api//\""
        } else if(variant.getName() ==~ /brand1Api[0-9]{2}Production.*/){
            variant.buildConfigField "String", "BASE_URL", "\"http://brand.one.production.api/\""
        } else if(variant.getName() ==~ /brand2Api[0-9]{2}Staging.*/) {
            variant.buildConfigField "String", "BASE_URL", "\"http://brand.two.staging.api//\""
        } else if(variant.getName() ==~ /brand2Api[0-9]{2}Production.*/){
            variant.buildConfigField "String", "BASE_URL", "\"http://brand.two.production.api/\""
        } else {
            throw new Exception("Unexpected variant name: " + variant.getName())
        }
    }
    

    I added an exception throw at the end of the chain so if anyone changes the variant names to ones unchecked here, the build would fail. This is important to avoid building applications with wrong endpoints.

    Works like a charm.