Android:如何为不同Flavor正确创建独立Source Set与多MainActivity?
Android Product Flavor 问题解决方案
一、Flavor2 源文件夹选项不显示的原因及修复
你的配置中,Flavour1和Flavour2同属flavour_1维度,IDE不显示Flavour2的源文件夹选项,核心问题在于sourceSets配置语法或物理目录未创建:
- 先手动在项目根目录下创建
src/Flavour2/java和src/Flavour2/res文件夹(注意名称大小写需与Gradle配置中的Flavour2完全一致)。 - 简化sourceSets配置,Gradle默认会自动识别
src/[Flavor名称]/结构的目录,无需手动指定srcDirs,可将配置修改为:
sourceSets { Flavour1.java.srcDirs += 'src/Flavour1/java' Flavour1.res.srcDirs += 'src/Flavour1/res' Flavour2.java.srcDirs += 'src/Flavour2/java' Flavour2.res.srcDirs += 'src/Flavour2/res' }
也可直接删除sourceSets配置,依赖默认规则。
3. 执行File -> Sync Project with Gradle Files同步项目,完成后即可看到Flavour2的源文件夹选项。
二、Flavor维度(flavorDimensions)的作用
Flavor维度是对Flavor进行分组并实现多维度组合构建的机制:
- 同一维度下的Flavor互斥,构建时同一维度仅能选择一个(如
flavour_1维度下的Flavour1和Flavour2无法同时构建)。 - 不同维度的Flavor可交叉组合生成构建变体(你的配置会生成
Flavour1Flavour3Debug、Flavour1Flavour3Release、Flavour2Flavour3Debug、Flavour2Flavour3Release这4种变体)。 - 维度常用于按功能/属性拆分Flavor,比如一个维度定义环境(dev/prod),另一个定义渠道(google/baidu),组合出多场景的构建变体。
三、不同Flavor配置独立MainActivity的正确方式
无需删除main目录下的文件,通过清单合并+源集覆盖/动态占位符即可实现:
方法1:Flavor源集覆盖MainActivity
- 在每个Flavor的源目录下创建对应MainActivity:
src/Flavour1/java/com/pkg/flavour_1/MainActivity.ktsrc/Flavour2/java/com/pkg/flavour_2/MainActivity.ktsrc/Flavour3/java/com/pkg/flavour_3/MainActivity.kt
- 在每个Flavor的
src/[Flavor名称]/AndroidManifest.xml中声明启动Activity,示例(Flavour1的清单):
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Flavor清单优先级高于main目录清单,构建对应变体时会自动使用Flavor内的Activity声明。
方法2:manifestPlaceholders动态指定
- 在main目录的AndroidManifest.xml中使用占位符定义Activity类名:
<activity android:name="${mainActivityClass}" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
- 在每个Flavor中配置占位符对应的值:
productFlavors { create("Flavour1") { applicationId = "com.pkg.flavour_1" dimension = "flavour_1" manifestPlaceholders["mainActivityClass"] = "com.pkg.flavour_1.MainActivity" } create("Flavour2") { applicationId = "com.pkg.flavour_2" dimension = "flavour_1" manifestPlaceholders["mainActivityClass"] = "com.pkg.flavour_2.MainActivity" } create("Flavour3") { applicationId = "com.pkg.flavour_3" dimension = "flavour_2" manifestPlaceholders["mainActivityClass"] = "com.pkg.flavour_3.MainActivity" } }
构建不同变体时,Gradle会自动替换占位符为对应Flavor的MainActivity类,无需修改main目录文件。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

