Flutter配置flavor后sourceSet未引用对应flavor目录资源问题
Flutter多Flavor资源加载异常修复方案
问题核心原因
你当前的配置存在两个问题,导致flavor资源无法正确覆盖main目录资源:
- 手动枚举res下所有子目录的写法错误:Android Gradle插件会自动识别res根目录下的所有标准资源子目录(drawable、mipmap、values等),你重复枚举子目录+根目录的操作会打乱资源索引顺序,破坏默认的flavor资源优先级规则。
- 对Android资源合并规则理解有误:Android构建默认采用资源合并逻辑,而非单目录加载逻辑:构建时优先级顺序为
构建类型资源 > flavor资源 > main资源 > 依赖库资源,当高优先级目录存在和低优先级目录同名、同类型、同配置限定符的资源时,高优先级资源会覆盖低优先级资源;如果高优先级目录不存在对应资源,才会回退到低优先级目录查找。系统默认不会完全忽略main目录的资源。
修复步骤
1. 精简sourceSet配置
删除所有手动罗列的res子目录配置,仅需指定每个flavor对应的res根目录即可,同时确保sourceSets配置块放在productFlavors配置块之前,修改后配置如下:
android { // sourceSets必须放在productFlavors之前 sourceSets { main { java.srcDirs += 'src/main/kotlin' res.srcDirs = ['src/main/res'] manifest.srcFile 'src/main/AndroidManifest.xml' } flavor1 { res.srcDirs = ['src/flavor1/res'] manifest.srcFile 'src/flavor1/AndroidManifest.xml' } flavor2 { res.srcDirs = ['src/flavor2/res'] manifest.srcFile 'src/flavor2/AndroidManifest.xml' } } flavorDimensions "app" productFlavors { flavor1 { dimension "app" applicationIdSuffix "" } flavor2 { dimension "app" applicationIdSuffix ".flavor2" } }
2. 删除冗余配置
你添加的afterEvaluate强制禁用资源任务缓存的配置没有实际作用,反而会导致资源索引无法正常增量更新,直接删除整段即可:
// 删除以下冗余配置 afterEvaluate { android.applicationVariants.all { variant -> tasks.named("generate${variant.name.capitalize()}ResValues") .configure { task -> task.outputs.upToDateWhen {false} } } }
3. 按需求配置资源加载规则
- 常规场景(推荐):公共资源放在
src/main/res目录下维护,每个flavor目录下仅放置需要差异化替换的同名、同类型资源,构建时会自动完成覆盖,不需要额外配置。 - 特殊场景(需完全不加载main目录资源):如果要求对应flavor仅加载自身目录下的资源,完全排除main目录资源,可在对应flavor配置中添加排除规则,以flavor2为例:
flavor2 { dimension "app" applicationIdSuffix ".flavor2" // 排除main目录下所有资源 sourceSets.main.res.exclude '**/*' }
注意:完全排除main目录资源会大幅增加重复资源维护成本,极易出现资源缺失导致的编译、运行时错误,非必要不使用该配置。
4. 清理缓存重新构建
配置修改完成后,执行以下命令清理旧构建产物,再启动对应flavor即可生效:
flutter clean cd android && ./gradlew clean cd .. && flutter run --flavor flavor2
内容的提问来源于stack exchange,提问作者Sandun Perera
相关产品推荐
相关产品推荐

