多国家Flavor的Android项目能否配置多个libs.versions.toml文件?
问题描述
我的Android应用有基于国家的多个Flavor,希望针对不同国家Flavor构建特定的依赖集。目前使用Version Catalog(libs.versions.toml)进行依赖管理,想知道是否可以配置多个libs.versions.toml文件,让不同国家Flavor对应使用仅包含所需依赖的文件。当前的libs.versions.toml内容如下:
[versions] agp = "8.2.0-alpha11" kotlin = "1.8.10" core-ktx = "1.9.0" junit = "4.13.2" androidx-test-ext-junit = "1.1.5" espresso-core = "3.5.1" lifecycle-runtime-ktx = "2.6.1" activity-compose = "1.7.0" compose-bom = "2023.03.00" uiautomator = "2.2.0" benchmark-macro-junit4 = "1.2.0-alpha16" appcompat = "1.6.1" material = "1.8.0" [libraries] core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" } espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso-core" } lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle-runtime-ktx" } activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activity-compose" } compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" } ui = { group = "androidx.compose.ui", name = "ui" } ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } material3 = { group = "androidx.compose.material3", name = "material3" } uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "uiautomator" } benchmark-macro-junit4 = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "benchmark-macro-junit4" } appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } material = { group = "com.google.android.material", name = "material", version.ref = "material" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } androidTest = { id = "com.android.test", version.ref = "agp" } [bundles]
解决方案
方案1:多Version Catalog文件(推荐)
Gradle支持加载多个Version Catalog文件,你可以为不同国家Flavor创建专属的Catalog变体,公共依赖保留在主文件中,Flavor专属依赖放在各自的文件里。
步骤1:创建Flavor专属Catalog文件
在gradle/目录下创建对应Flavor的toml文件,比如:
libs.versions.us.toml(美国Flavor)libs.versions.cn.toml(中国Flavor)
这些文件只包含对应Flavor需要的依赖,比如libs.versions.us.toml可以这样写:
[libraries] us-payment-sdk = { group = "com.us.payment", name = "sdk", version = "3.1.0" } us-location-service = { group = "com.us.location", name = "service", version = "2.0.5" }
步骤2:在Settings中加载对应Catalog
修改项目根目录的settings.gradle.kts,根据构建时指定的Flavor加载对应的Catalog:
// settings.gradle.kts val buildFlavor = System.getenv("BUILD_FLAVOR") ?: "default" dependencyResolutionManagement { repositories { google() mavenCentral() } versionCatalogs { // 加载主公共Catalog create("libs") { from(files("gradle/libs.versions.toml")) } // 加载Flavor专属Catalog(如果指定了非默认Flavor) if (buildFlavor != "default") { create("libs${buildFlavor.replaceFirstChar { it.uppercase() }}") { from(files("gradle/libs.versions.${buildFlavor}.toml")) } } } }
构建时通过环境变量指定Flavor,比如:
# 构建美国Flavor BUILD_FLAVOR=us ./gradlew assembleUsRelease
步骤3:在模块构建脚本中引入Flavor专属依赖
修改app/build.gradle.kts,为每个Flavor配置专属依赖:
// app/build.gradle.kts android { flavorDimensions += "country" productFlavors { create("us") { dimension = "country" } create("cn") { dimension = "country" } } } dependencies { // 公共依赖,所有Flavor都引入 implementation(libs.core.ktx) implementation(libs.lifecycle.runtime.ktx) implementation(libs.activity.compose) // ...其他公共依赖 // 美国Flavor专属依赖 productFlavors.named("us") { dependencies { implementation(libsUs.us.payment.sdk) implementation(libsUs.us.location.service) } } // 中国Flavor专属依赖 productFlavors.named("cn") { dependencies { implementation(libsCn.cn.payment.sdk) implementation(libsCn.cn.map.service) } } }
方案2:主Catalog中定义Flavor专属依赖组
如果不想创建多个toml文件,可以在主libs.versions.toml中为不同Flavor单独定义依赖条目,再通过构建脚本按Flavor引入。
修改主Catalog文件
在libs.versions.toml的[libraries]块中添加Flavor专属依赖:
[libraries] # 公共依赖(原有内容保留) core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" } # ... # US Flavor专属 us-payment-sdk = { group = "com.us.payment", name = "sdk", version = "3.1.0" } # CN Flavor专属 cn-payment-sdk = { group = "com.cn.payment", name = "sdk", version = "1.5.2" }
在构建脚本中按Flavor引入
// app/build.gradle.kts android { flavorDimensions += "country" productFlavors { create("us") { dimension = "country" } create("cn") { dimension = "country" } } } dependencies { // 公共依赖 implementation(libs.core.ktx) // ... // 为每个Flavor绑定专属依赖 productFlavors.forEach { flavor -> when (flavor.name) { "us" -> implementation(libs.us.payment.sdk) "cn" -> implementation(libs.cn.payment.sdk) } } }
方案3:条件化依赖引入(简单场景适用)
通过检测当前构建任务的名称,判断要引入的Flavor专属依赖,适合依赖较少的场景:
// app/build.gradle.kts android { flavorDimensions += "country" productFlavors { create("us") { dimension = "country" } create("cn") { dimension = "country" } } } dependencies { // 公共依赖 implementation(libs.core.ktx) // ... // 根据构建任务判断引入对应依赖 if (gradle.startParameter.taskNames.any { it.contains("Us") }) { implementation(libs.us.payment.sdk) } if (gradle.startParameter.taskNames.any { it.contains("Cn") }) { implementation(libs.cn.payment.sdk) } }
内容的提问来源于stack exchange,提问作者Akshay Kotecha
相关产品推荐
相关产品推荐

