Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Folder naming convention for gradle build variants

I have been struggling for a while with gradle and build variants.

I have these build types defined:

  • debug
  • release

And these flavors:

  • free
  • paid

How can i define unique resources and assets for a certain build variant ie. FreeDebug? For example I want four different app names depending on build variant, and a different icon for each variant.

like image 642
JeoPeo Avatar asked Oct 28 '13 21:10

JeoPeo


1 Answers

I have been struggling with the same problem. At first I used two branches in my source control, but that was a head ache keeping them in sync. Gradle is a very flexible build system, but the default conventions are not always enough. Here is how I finally resolved it in my code base.

I ended up with essentially the following directory structure (simplified):

+ src
  + main
  | + res
  | | + values
  | |   - strings.xml
  | + java
  |    ...  
  + debug
  | + free
  | | + res
  | |   + values
  | |     - strings.xml
  | + paid
  |   + res
  |    + values
  |      - strings.xml
  + free
  | + res
  | | + values
  | |   - strings.xml
  | + java
  |    ...  
  + paid
    + res
    | + values
    |   - strings.xml
    + java
       ...  

In the main folder I keep everything that is common for both flavors. In the free folder I keep everything that is unique for the free version (same for paid). The files in the flavor folder will be overlaid on top of main.

The default overlay rules will handle the product flavors "free" and "paid" by using the folders under "src" with the same names. The problem for me started starts with the overlay of build types.

If I created a debug folder with the same structure as the flavor folders it would be overlaid on top of the currently used flavor folder. That led to the same debug-name for both flavors, but I wanted different debug names depending on flavor. After some research I came up with the following modification to my build file.

...

android {
    buildTypes {
        debug {
            ...
        }
        release {
            ...
        }
    }

    productFlavors {
        free {}
        paid {}
    }
}

android.applicationVariants.all { variant ->
    if (variant.buildType.name == "release") {
        ...
    }
    else if (variant.buildType.name == "debug") {
        switch (variant.name) {
            case "FreeDebug":
                variant.mergeResources.doFirst {
                    android.sourceSets.debug.setRoot("src/debug/free")
                }
                break;
            case "PaidDebug":
                variant.mergeResources.doFirst {
                    android.sourceSets.debug.setRoot("src/debug/paid")
                }
                break;
        }
    }
}

...

Now the build variant will be built by first overlaying the following folders:

PaidRelease -> /src/main + /src/paid
PaidDebug   -> /src/main + /src/paid + /src/debug/paid

FreeRelease -> /src/main + /src/free
FreeDebug   -> /src/main + /src/free + /src/debug/free
like image 96
ddante Avatar answered Sep 22 '22 14:09

ddante