Gradle:多维度Flavor ApplicationId

9

我有一个比较复杂的项目,需要每个应用程序都有两个口味维度。在下面的示例中,我已经将其重新编写得更加简单:

flavorDimensions "shape", "color"

productFlavors {

     blue {
         flavorDimension "color"
     }

     red {
         flavorDimension "color"
     }

     green {
         flavorDimension "color"
     }


     square {
         flavorDimension "shape"
     }

     circle {
         flavorDimension "shape"
     }

我希望能够为每个变体设置不同的应用程序ID,例如:squareblue将具有与circleblue不同的应用程序ID。我不能在颜色维度中设置应用程序ID,因为对于每个形状来说它都是相同的。在上面的示例中,我需要有6个不同的应用程序ID。这些ID也没有遵循任何模式,它们可以是任何内容。
我在这里看到了答案:如何使用flavorDimensions为每个风味组合设置不同的applicationId?但这意味着我需要手动设置它,这对于我的项目来说不可行,因为变体数量太多(成千上万)。
我真正想做的是在颜色维度上设置两个应用程序ID,然后在构建时根据形状维度选择正确的应用程序ID。我尝试定义变量,但没有成功,它们只会被最后一个变体覆盖。

2
你的构建文件是用图灵完备语言编写的,因此你有很大的潜力。难道你不能在那个链接问题中的代码基础上进行扩展,添加自己的逻辑来生成应用程序ID吗? - Scott Barta
ApplicationIDs已经存在并且可以是任何内容,因此没有逻辑方法来创建它们。我可以将每一个都添加到variantFilter中,但这将涉及向我的gradle文件添加数千行额外的代码来检查每个变体。 - David Scott
如果没有逻辑的方法来创建它们,我不确定是否有合理的替代方案 - 你必须在某个地方硬编码它们。你可以将它们保存在CSV文本文件中,并在构建文件中编写代码来读取该文件并将其应用到映射中。 - Scott Barta
啊,我知道我必须硬编码它们,但我想将其添加到productFlavor中。因此,我会有类似于applicationIdSquare和applicationIdCircle的东西,并且它会根据其他flavor维度选择正确的一个。 - David Scott
3个回答

1

Gradle内置了extras属性,因此您可以在不定义类的情况下执行此操作。

可能会看起来像这样,可能会有一两个拼写错误:

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

0
def appId = "my.custom.package"

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

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

0

我在这个例子中找到了一个解决方案:Gradle Android Plugin - add custom flavor attribute?

如果你在gradle文件中添加一个像这样的类,你就可以给产品风味添加自定义属性。

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
    }

}

将以下代码添加到android { }部分的开头,然后将其扩展到每种风味。
productFlavors.whenObjectAdded { flavor ->
    flavor.extensions.create("shapeIds", AppIdExtension, "", "")
}

然后在你的产品口味中,你可以为每种形状类型设置值

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

最后,在您的productFlavors { }部分之后,添加以下内容:

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

}

这可能不是最优雅或高效的实现方式,但对我来说完美运作。现在我可以在productFlavor部分中添加所有我的Id,然后variantFilter根据第一个flavor设置正确的applicationId。


添加一个针对每个口味的扩展似乎是一个不错的解决方案。(针对每个口味的额外属性也应该可以工作。)您可以/应该使用productFlavors.all { ... }而不是productFlavors.whenObjectAdded { ... } - Peter Niederwieser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接