【问题标题】:How to set different applicationId for each flavor combination using flavorDimensions when using Gradle Kotlin-DSL?使用 Gradle Kotlin-DSL 时如何使用 flavorDimensions 为每种风味组合设置不同的 applicationId?
【发布时间】:2020-02-06 21:13:22
【问题描述】:

我正在使用 Kotlinscript 文件将 Android 应用程序转换为 Gradle Kotlin-DSL。

我在转换 applicationId 逻辑时遇到问题。我们不使用defaultConfigurationapplicationId 以及各种applicationIdSuffix 来满足我们的口味,而是使用自定义逻辑。逻辑在this SO answer中描述,这里是groovy代码:

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

使用 kotlin,我无法像在 groovy 中那样更改 mergedFlavorapplicationId。它是一个 val,因此无法更改。

任何优雅的解决方案来解决这个问题?

【问题讨论】:

    标签: android gradle gradle-kotlin-dsl


    【解决方案1】:

    Google 在 Android Gradle 插件 7.0.0 中添加了变体 API。有了它,我们可以更改applicationId

    android {
        flavorDimensions.addAll(listOf("price", "dataset"))
    
        productFlavors {
            create("free") { dimension = "price" }
            create("pro") { dimension = "price" }
            create("dataset1") { dimension = "dataset" }
            create("dataset2") { dimension = "dataset" }
        }
    }
    
    androidComponents {
        onVariants { variant ->
            val applicationId = when(variant.flavorName) {
                "freeDataset1" -> "com.beansys.freeappdataset1"
                "freeDataset2" -> "com.beansys.freedataset2"
                "proDataset1" -> "com.beansys.dataset1paid"
                "proDataset2" -> "com.beansys.mypaiddataset2"
                else -> throw(IllegalStateException("Whats your flavor? ${variant.flavorName}!"))
            }
            variant.applicationId.set(applicationId)
        }
    }
    

    请注意,最好使用任务来确定applicationId

    有关更多信息,请参阅以下资源:

    【讨论】:

    • 你可以为 groovy 添加相同的脚本吗?对我很有帮助。
    • @S.Gissel 在几年前才为 Groovy 找到解决方案后,我为 Kotlin DSL 创建了这个问题。您可以在那里找到该问题和相应的 Groovy 解决方案:stackoverflow.com/a/68835727/2793394
    【解决方案2】:

    // 更新:现在有一种非 hacky 的方式来做到这一点。见我的other answer

    // 原答案: 诀窍是将mergedFlavor 转换为MergedFlavor,然后更改applicationId

    import com.android.build.gradle.internal.core.MergedFlavor
    
    android {
        flavorDimensions("price", "dataset")
    
        productFlavors {
            create("free") { dimension = "price" }
            create("pro") { dimension = "price" }
            create("dataset1") { dimension = "dataset" }
            create("dataset2") { dimension = "dataset" }
        }
    
        android.applicationVariants.all {
            val applicationId = when(name) {
                "freeDataset1" -> "com.beansys.freeappdataset1"
                "freeDataset2" -> "com.beansys.freedataset2"
                "proDataset1" -> "com.beansys.dataset1paid"
                "proDataset2" -> "com.beansys.mypaiddataset2"
                else -> throw(IllegalStateException("Whats your flavor? $name!"))
            }
            (mergedFlavor as MergedFlavor).applicationId = applicationId
        }
    }
    

    感谢任何更清洁的解决方案!

    // 历史:

    最初,此答案包含对 DefaultProductFlavor 的强制转换,自 Android Gradle 插件 4.0.0 以来不起作用,对AbstractProductFlavor 的强制转换现在已弃用。

    【讨论】:

    • AbstractProductFlavor 也已弃用
    • @Mark,有一个新的替代方案,请参阅下面的更新答案或其他答案。
    【解决方案3】:

    添加到 Henning's answer 并由 Mark 评论 AbstractProductFlavor 已弃用,您可以改为转换为 MergedFlavor

    (mergedFlavor as com.android.build.gradle.internal.core.MergedFlavor).applicationId = applicationId
    

    使用 Android Gradle Plugin 4.1.2 测试,但我猜它从 4.0.0 开始有效

    【讨论】:

    • 感谢您的提示!击败我的@Suppress("DEPRECATION") 注释:-D。我更新了我的答案
    • 谢谢!它是在“内部”包中的事实,是否可能是未来的问题?
    • 好吧,现在使用getApplicationId 也会显示弃用警告。因此,在某些时候,这也可能不再起作用。我们最近遇到了一个问题,即第 3 方插件没有获取我们通过这种方法定义的正确应用程序 ID。似乎这取决于何时有人请求最终的应用程序 ID...
    猜你喜欢
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多