You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gradle升级至7.3.3后main作为productFlavors名报重复键错误

问题原因

Gradle 7.3及以上版本将main设为内置保留命名,会为所有项目默认预注册对应核心源集(SourceSet)。在productFlavors中手动声明同名main风味时,会触发同键重复注册,抛出Multiple entries with same key: main=[] and main=[]报错,修改flavor名称后冲突消失就是这个原因。

推荐方案(无兼容风险,完全保留main的使用体验)

不需要强行占用内置保留名,通过内部临时命名+映射规则的方式,可实现和直接命名main完全一致的使用效果,不会引发版本兼容问题:

  • 第一步:将productFlavors中原本的main风味改为临时内部名(比如mainCore),原有配置完全保留,不需要修改任何逻辑
flavorDimensions "mode", "client"
productFlavors {
    /////// Distribution Modes ///////
    mainCore { // 仅内部注册使用,对外不暴露
        dimension "mode"
        versionName generateVersionName()
        manifestPlaceholders = [
                app_label: "@string/app_name",
                appIcon: "@mipmap/ic_launcher",
                appIconRound: "@mipmap/ic_launcher_round"
        ]
    }
    beta {
        dimension "mode"
        applicationIdSuffix ".beta"
        manifestPlaceholders = [
                app_label: "@string/app_name",
                appIcon: "@mipmap/ic_launcher_beta",
                appIconRound: "@mipmap/ic_launcher_beta_round"
        ]
    }
    // 其余原有flavor配置保持不变
}
  • 第二步:在android配置块内(productFlavors块之后)添加映射规则,让内部临时名完全对外替换为main,不需要调整原有项目目录结构:
android {
    // 其余原有配置(compileSdk、defaultConfig等)保持不变

    // 1. 源集映射:直接读取原有src/main路径下的代码、资源,不需要移动文件
    sourceSets {
        mainCore {
            java.srcDirs = ['src/main/java']
            res.srcDirs = ['src/main/res']
            manifest.srcFile 'src/main/AndroidManifest.xml'
            jniLibs.srcDirs = ['src/main/jniLibs']
            assets.srcDirs = ['src/main/assets']
        }
    }

    // 2. 构建产物名映射:输出apk/aab时自动替换mainCore为main
    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            output.outputFileName = output.outputFileName.replace("mainCore", "main")
        }
    }

    // 3. 构建任务别名:保留原有的assembleMain、installMain等命令使用习惯
    gradle.projectsEvaluated {
        tasks.matching { it.name.contains("MainCore") }.all { originTask ->
            def aliasName = originTask.name.replace("MainCore", "Main")
            tasks.create(aliasName) {
                dependsOn originTask
                group = originTask.group
            }
        }
    }
}

配置完成后同步Gradle即可,使用体验和直接将flavor命名为main没有区别:原有代码路径不需要修改、构建命令可以继续用main关键字、产物命名正常显示main,且不会触发版本兼容问题。

备选Hack方案(可直接在productFlavors中写main,存在兼容风险)

如果一定要直接在productFlavors块中声明main,可以在app模块build.gradle文件的最顶部(android块之前)加入如下配置,提前移除内置注册的main源集规避冲突:

// 注意:该方案为非官方hack手段,后续升级Gradle/AGP版本时可能失效
afterEvaluate {
    android.sourceSets.remove(android.sourceSets.findByName("main"))
}

添加后即可正常在productFlavors中声明main风味,注意需要在main风味配置中补全默认源集路径绑定,否则会找不到代码、资源文件。

内容的提问来源于stack exchange,提问作者Orcun Sevsay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 10:57:20