Android多渠道构建:Paid渠道仅用自定义Login.java的配置问题
需求
创建Free和Paid两种Flavor,Paid版本仅使用Paid目录下的Login.java,其余类文件复用Free目录的内容。
你的尝试问题分析
- 直接替换Paid的源码目录为Free的:
sourceSets { paid { java { srcDirs = ['src/free/java'] } } }
问题:这种写法会完全覆盖Paid flavor的默认源码目录(src/paid/java),导致Paid自己的Login.java不被编译,所有类都用Free的版本。
- 尝试排除Free的
Login.java但报错:
sourceSets { paid { java { srcDirs = ['src/free/java'] exclude 'package/Login.java' } } }
问题:一是exclude路径错误(需使用包名的斜杠分隔路径,比如com/example/app/Login.java);二是没有将Paid自身的源码目录加入,排除Free的Login.java后找不到对应的类。
正确解决方案
方案一:基于现有结构的sourceSets配置
修改Module级build.gradle中的sourceSets配置,让Paid flavor同时包含自身和Free的源码目录,且Paid目录优先级更高:
android { flavorDimensions "version" productFlavors { free { dimension "version" } paid { dimension "version" } } sourceSets { paid { // 保留Paid自身的源码目录,再添加Free的源码目录 java.srcDirs += 'src/free/java' } } }
原理:Gradle编译时会优先使用Flavor自身目录(src/paid/java)中的文件,当该目录没有对应类时,才会去Free的目录查找,这样Paid的Login.java会覆盖Free的同名文件,其余类自动复用Free的版本。
方案二:更规范的项目结构调整(推荐)
将公共类(Utils.java、Test.java)移到src/main/java目录下,Free和Paid目录仅保留各自的Login.java,无需额外修改sourceSets:
src | +-main | | | +-java | | | +-package | | | +- Utils.java | +- Test.java +-free | | | +-java | | | +-package | | | +- Login.java +-paid | +-java | +-package | +- Login.java
此时只需配置基础的productFlavors即可:
android { flavorDimensions "version" productFlavors { free { dimension "version" } paid { dimension "version" } } }
原理:Android Gradle插件默认会优先使用当前Flavor目录中的类,当Flavor目录没有对应类时,会自动使用main目录中的公共类,这种结构更符合Android项目的最佳实践,便于维护。
内容的提问来源于stack exchange,提问作者user2659769

