9

I have a relatively complicated project that requires two flavor dimensions for each app. I've rewritten it much more simply in the example below:

flavorDimensions "shape", "color"

productFlavors {

     blue {
         flavorDimension "color"
     }

     red {
         flavorDimension "color"
     }

     green {
         flavorDimension "color"
     }


     square {
         flavorDimension "shape"
     }

     circle {
         flavorDimension "shape"
     }

I want to be able to set a different applicationId for each variant, eg: squareblue would have a different applicationId to circleblue. I can't set the applicationId in the color dimension because it would be the same for each shape. I would need to have 6 different applicationIds in the above example. These Ids also don't follow any pattern, they could be anything.

I've seen the answer here: How to set different applicationId for each flavor combination using flavorDimensions? but that would mean I need to set it up manually, which isn't feasible for my project, due to the number of variants (1000s).

What I really want to do is set two applicationids on the color dimension, then it picks the correct one, depending on the shape dimension, when it's built. I've tried defining variables but haven't had any success with that, they just get overwritten by the last variant.

Community
  • 1
  • 1
David Scott
  • 1,666
  • 12
  • 22
  • 2
    Your build files are written in a Turing-complete language, so you have the potential to do quite a bit. Can't you build on the code in that question you linked to and add your own logic to generate application IDs? – Scott Barta Oct 28 '14 at 16:03
  • The ApplicationIDs are already existing and could be anything, so there's no logical way of creating them. I could add each one in the variantFilter, but that would involve adding thousands of extra lines to my gradle file to check through every variant. – David Scott Oct 28 '14 at 16:11
  • If there's no logical way of creating them, I'm not sure what reasonable alternative there is -- you'll have to hardcode them somewhere. You could perhaps save them in a CSV text file and write code in the build file to read that into a map and apply it. – Scott Barta Oct 28 '14 at 16:13
  • Ah yes I know I have to hard code them, what I want is to add it to the productFlavor. So I would have something like applicationIdSquare and applicationIdCircle and it picks the correct one, depending on the other flavor dimension. – David Scott Oct 28 '14 at 16:17

3 Answers3

1

Gradle has an extras property built in, so you could do this without defining a class.

Would look something like this, might have made a typo or two:

productFlavors {
    blue {
        flavorDimension "color"
        ext.squareId = "yourAppId"
        ext.circleId = "yourAppId"
    }

    android.applicationVariants.all { variant ->
        def flavors = variant.getFlavors()
        if (flavors[0].name.equals("square")){
            variant.mergedFlavor.setApplicationId(flavors[1].ext.squareId)
        } ...
    }
Chris
  • 5,876
  • 3
  • 43
  • 69
0

I found a solution following from this example here: Gradle Android Plugin - add custom flavor attribute?

If you add a class like this to your gradle file you can add custom attributes to a productFlavor

class AppIdExtension {
    String squareId
    String circleId

    AppIdExtension(String sId, String cId){
        squareId = sId
        circleId = cId
    }

    public void setSquareId(String id){
        squareId = id
    }

    public String getSquareId(){
        squareId
    }

    public void setCircleId(String id){
        circleId = id
    }

    public String getCircleId(){
        circleId
    }

}

You then add this to extension to each flavor by adding the following code at the start of your android { } section

productFlavors.whenObjectAdded { flavor ->
    flavor.extensions.create("shapeIds", AppIdExtension, "", "")
}

Then inside your product flavor you can set the values for each shape type

blue {
        flavorDimension "color"
        platformIds.squareId "yourAppId"
        platformIds.circleId "yourAppId"
    }

Then finally after your productFlavors { } section you add the following:

android.variantFilter { variant ->
    def applicationId = ""
    def flavors = variant.getFlavors()

  if(flavors[0].name.equals("square")){
      applicationId = flavors[1].platformIds.squareId
   } else if(flavors[0].name.equals("circle")){
      applicationId = flavors[1].platformIds.circleId
   }

   variant.getDefaultConfig().applicationId applicationId

}

This may not be the most elegant or efficient way of achieving it, but it is working perfectly for me. Now I can add all of my Ids in the productFlavor section and then the variantFilter sets the correct applicationId depending on the first flavor.

Community
  • 1
  • 1
David Scott
  • 1,666
  • 12
  • 22
  • Adding a per-flavor extension sounds like a good solution. (Per-flavor extra properties should have worked as well.) Instead of `productFlavors.whenObjectAdded { ... }`, you can/should use `productFlavors.all { ... }`. – Peter Niederwieser Oct 29 '14 at 12:05
0
def appId = "my.custom.package"

if (appId == "some.package") { 
     ..... Change conditions based on the flavors maybe defined more variables
}

defaultConfig {
        applicationId "${appId}"
       ...............
}