如何在Gradle构建变体中为特定Flavor隔离库依赖与代码配置
首先纠正你Gradle依赖里的一个小问题:PaidImplementation要改成paidImplementation(flavor名称是小写的paid,依赖配置需对应小写开头的驼峰命名),否则这个依赖不会正确关联到paid flavor。
接下来按以下步骤实现特定代码、资源仅作用于对应Product Flavor:
1. 按Flavor分离代码目录
在项目的src目录下创建对应flavor的源码目录结构,目录命名必须和flavor名称完全一致(小写):
- 针对paid flavor:创建
src/paid/java/、src/paid/res/、src/paid/AndroidManifest.xml - 针对free flavor:创建
src/free/java/、src/free/res/、src/free/AndroidManifest.xml
把仅属于paid flavor的代码(比如Facebook登录相关的Java/Kotlin类)放到src/paid/java/下对应的包路径中;仅属于free flavor的代码(比如下拉刷新相关逻辑)放到src/free/java/下。
编译不同flavor时,只会加载对应目录下的代码,其他flavor的代码不会被打包,也不会出现编译错误。
2. Flavor专属Manifest配置
每个flavor的Manifest文件只存放该flavor需要的组件配置:
- 比如在
src/paid/AndroidManifest.xml中添加Facebook登录所需的Activity、权限等:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.INTERNET" /> <application> <activity android:name="com.facebook.FacebookActivity" android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:label="@string/app_name" /> <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id" /> </application> </manifest>
- free flavor的Manifest如果没有额外配置,可以留空或者只加自己需要的内容。
主模块的src/main/AndroidManifest.xml只存放所有flavor共用的配置,编译时Gradle会自动合并主Manifest和对应flavor的Manifest。
3. 主模块代码中的Flavor条件判断
如果主模块中有部分逻辑需要根据当前flavor执行不同操作,可以使用自动生成的BuildConfig类中的常量进行判断:
if ("paid".equals(BuildConfig.FLAVOR)) { // 执行paid flavor专属逻辑,比如初始化Facebook登录 } else if ("free".equals(BuildConfig.FLAVOR)) { // 执行free flavor专属逻辑,比如初始化下拉刷新 }
注意:不要在主模块中直接引用flavor专属目录中的类,否则编译其他flavor时会出现找不到类的错误,必须把这类专属类放到对应flavor的源码目录中。
4. 验证配置
编译对应flavor的APK时,可以通过以下方式验证:
- 执行
./gradlew assemblePaidRelease或者./gradlew assembleFreeRelease生成对应APK - 查看APK的内容,确认仅包含对应flavor的依赖、代码和Manifest配置
内容的提问来源于stack exchange,提问作者Vijay Rathod

