【问题标题】:How to set different applicationId for each flavor combination using flavorDimensions?如何使用 flavorDimensions 为每种风味组合设置不同的 applicationId?
【发布时间】:2014-10-24 12:07:20
【问题描述】:

我有一个旧的 android 应用程序,我正在尝试迁移到 android gradle 构建系统。该应用程序当前构建在多项目设置中,并作为四个不同的应用程序发布(包括两个不同的数据集和两个数据集的免费/付费版本)。我已经设法通过使用 flavorDimensions(以前称为 flavorGroups)摆脱了多项目设置,但我不知道如何为每个风味组合设置不同的 applicationId。

由于应用程序版本已经发布,我需要保持与当前相同的应用程序 ID。由于我的原始包命名是如何完成的,我不能简单地使用带有“packageNameSuffix”的flavor-buildtype组合(如果它是一个未发布的应用程序,这将是一个很好的选择)。

https://stackoverflow.com/a/20956353/4177090 正在回答如何使用不同的源文件夹进行风味组合,而不是如何(如果可能的话)为构建文件中的每个组合设置特定配置。

Gradle 构建文件 sn-p:

flavorDimensions "price", "dataset"

productFlavors {
    free { flavorDimension "price" }
    paid { flavorDimension "price" }
    dataset1 { flavorDimension "dataset" }
    dataset2 { flavorDimension "dataset" }
}

我想在我的 gradle 构建文件中包含以下内容(注意我的命名是多么不合逻辑,这就是我不能使用 packageNameSuffix 的原因):

freeDataset1 { applicationId "com.beansys.freeappdataset1" }
freeDataset2 { applicationId "com.beansys.freedataset2" }
paidDataset1 { applicationId "com.beansys.dataset1paid" }
paidDataset2 { applicationId "com.beansys.mypaiddataset2" }

【问题讨论】:

  • 你为什么不放弃尺寸并创造不同的口味?
  • 感谢您的建议。我可以这样做,但在这种情况下,我必须复制风味源文件夹,即 dataset1 数据将被复制到文件夹 freeDataset1 和文件夹paidDataset1。如果复制代码和数据是我唯一的选择,我宁愿“回到”使用多项目解决方案(不是很干净,但至少比复制我的源文件夹内容更好)。
  • 你为什么要链接建议多个文件夹的答案呢?
  • 我链接到该答案,因为它显示了如何使用“风味组合”源文件夹(即,自从 android 插件版本 0.7.0 以来,它可以使用具有组合风味名称的源文件夹)。然而,从 mm2001 到该答案的评论中的问题与我的问题非常接近。遗憾的是,mm2001 还没有对这个问题做出任何回应,这就是为什么我认为在这里对问题进行更广泛的解释是个好主意。

标签: android gradle android-gradle-plugin android-build


【解决方案1】:

Fredrik 提出的解决方案在将 Android Studio 升级到 1.0.2(并将 gradle 插件升级到 1.0.0)后停止工作,所以我必须添加以下更改,从 gradle 插件 1.3.1 开始:

flavorDimensions "price", "dataset"

productFlavors {
    free { dimension "price" }
    paid { dimension "price" }
    dataset1 { dimension "dataset" }
    dataset2 { dimension "dataset" }
}

android.applicationVariants.all { variant ->
    def mergedFlavor = variant.mergedFlavor
    switch (variant.flavorName) {
        case "freeDataset1":
            mergedFlavor.setApplicationId("com.beansys.freeappdataset1")
            break
        case "freeDataset2":
            mergedFlavor.setApplicationId("com.beansys.freedataset2")
            break
        case "paidDataset1":
            mergedFlavor.setApplicationId("com.beansys.dataset1paid")
            break
        case "paidDataset2":
            mergedFlavor.setApplicationId("com.beansys.mypaiddataset2")
            break
    }
}

【讨论】:

  • 我也是这样做的。我尝试转换为 Kotlinscript,但 mergeFlavor 的 applicationId 是 val,因此不提供 setter。你知道如何解决这个问题吗?
  • Gradle Kotlin DSL 的解决方案在这里:stackoverflow.com/a/60103604/2793394
【解决方案2】:

我终于设法解决了这个问题。我认为该解决方案很优雅(尽管实际代码很可能由具有 groovy 知识的人编写得更好)。

为每种组合风味设置特定 applicationId 的解决方案:

flavorDimensions "price", "dataset"

productFlavors {
    free { flavorDimension "price" }
    paid { flavorDimension "price" }
    dataset1 { flavorDimension "dataset" }
    dataset2 { flavorDimension "dataset" }
}

android.variantFilter { variant ->
    def flavorString = ""
    def flavors = variant.getFlavors()
    for (int i = 0; i < flavors.size(); i++) {
        flavorString += flavors[i].name;
    }
    if(flavorString.equalsIgnoreCase("freeDataset1")) {
        variant.getDefaultConfig().applicationId "com.beansys.freeappdataset1"
    }
    if(flavorString.equalsIgnoreCase("freeDataset2")) {
        variant.getDefaultConfig().applicationId "com.beansys.freedataset2"
    }
    if(flavorString.equalsIgnoreCase("paidDataset1")) {
        variant.getDefaultConfig().applicationId "com.beansys.dataset1paid"
    }
    if(flavorString.equalsIgnoreCase("paidDataset2")) {
        variant.getDefaultConfig().applicationId "com.beansys.mypaiddataset2"
    }
}

【讨论】:

    【解决方案3】:

    我在将给出的答案转换为 gradle kotlin dsl 时遇到问题。我找到了解决方案并在这里分享:https://stackoverflow.com/a/60103604/2793394

    【讨论】:

      【解决方案4】:

      对于 AGP 7.0,您应该使用 onVariants:

      androidComponents {
         onVariants(selector().all(), { variant ->
            switch (variant.name) {
               case "freeDataset1":
                  variant.applicationId = "com.beansys.freeappdataset1"
                  break
               case "freeDataset2":
                  variant.setApplicationId = "com.beansys.freedataset2"
                  break
               ...
               ...
               ...
            }
         })
      }
      

      您甚至可以传递您的自定义“选择器”并为特定变体做一些事情:

      androidComponents {
         onVariants(selector().withName("paidDataset1"), { variant ->
            variant.applicationId = "com.beansys.dataset1paid"
         })
      }
      

      【讨论】:

        猜你喜欢
        • 2020-07-29
        • 1970-01-01
        • 2019-01-16
        • 2019-08-06
        • 2021-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多