Android Studio中为不同Product Flavor配置源集的包含与排除
你的问题出在错误地修改了main sourceSet——当你在每个flavor配置里给main.java.srcDirs添加目录时,这些目录会被加入到所有flavor共享的main sourceSet中,所以不管编译哪个flavor,所有feature目录的代码都会被包含进来,自然无法实现按需编译。
下面给你两种可行的解决方案,按需选择:
方案一:使用Flavor专属的SourceSet
直接为每个flavor配置独立的sourceSet,让它们指向对应的feature目录,而main sourceSet只保留公共的common代码。这样编译某个flavor时,只会合并main和该flavor专属的sourceSet代码:
android { productFlavors { flavor1 {} flavor2 {} } sourceSets { main { java.srcDir 'path_to_my_dir/common' } // 为flavor1配置专属sourceSet flavor1 { java.srcDir 'path_to_my_dir/feature1' } // 为flavor2配置专属sourceSet,支持多个目录 flavor2 { java.srcDir 'path_to_my_dir/feature2' java.srcDir 'path_to_my_dir/feature3' } } }
这种方式不需要修改productFlavors内部的sourceSet配置,而是直接在全局sourceSets中定义每个flavor的专属目录,Gradle会自动在编译对应flavor时合并这些目录的代码。
方案二:模块化拆分(推荐)
把common、feature1、feature2、feature3分别做成独立的Android Library模块,然后通过flavor-specific的依赖来控制编译哪些模块。这种方式更符合模块化开发的最佳实践,代码隔离更清晰,维护也更方便:
- 先把common、feature1、feature2、feature3分别创建为Library模块(比如
:common、:feature1、:feature2、:feature3) - 在主模块的
build.gradle中配置依赖:
android { productFlavors { flavor1 {} flavor2 {} } } dependencies { // common模块始终编译 implementation project(':common') // 只有flavor1编译时才依赖feature1 flavor1Implementation project(':feature1') // 只有flavor2编译时才依赖feature2和feature3 flavor2Implementation project(':feature2') flavor2Implementation project(':feature3') }
这种方式下,Gradle会根据当前编译的flavor自动引入对应的模块依赖,完全避免了代码混编的问题。
为什么你之前的exclude写法无效?
你尝试的flavor2 { main.java.excludes += [ 'path_to_my_dir/feature1' ] }无效,是因为main sourceSet是所有flavor共享的,你在flavor2里修改main的exclude,只会影响flavor2编译时的main目录,但如果其他flavor已经把feature1加到了main的srcDirs里,这个exclude的作用范围有限,而且路径写法也容易出错(比如需要匹配相对路径或者完整路径),所以不推荐用这种方式。
内容的提问来源于stack exchange,提问作者deko

