Gradle: Multi-Dimension Flavor ApplicationId

2019-04-06 14:14发布

问题:

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.

回答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)
        } ...
    }


回答2:

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.



回答3:

def appId = "my.custom.package"

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

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