一、多风味项目搭建:免费版与付费版
说实话,刚接触 Android 构建变体时,我也觉得这东西有点绕。但用顺手之后,你会发现它简直是项目管理的利器。今天我们就从零开始,搭一个同时支持免费版和付费版的项目。
1.1 什么是构建变体?
构建变体 = 构建类型 × 产品风味。说白了,就是「调试版免费 App」和「发布版付费 App」这样的组合。我在一个电商项目里,就靠这个同时维护了国内版和海外版,省了不少事。
核心概念:
- 构建类型(Build Type): debug / release,控制是否可调试、是否混淆
- 产品风味(Product Flavor): free / paid,控制功能差异、包名、图标
1.2 在 build.gradle 中配置
打开 app 模块的 build.gradle,在 android 块里加上 flavor 配置。我习惯把 flavor 写在 buildTypes 后面,结构更清晰。
android {
compileSdk 34
defaultConfig {
applicationId "com.example.myapp"
minSdk 24
targetSdk 34
versionCode 1
versionName "1.0"
}
buildTypes {
debug {
isDebuggable = true
applicationIdSuffix ".debug"
}
release {
isMinifyEnabled = true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
flavorDimensions "version"
productFlavors {
free {
dimension "version"
applicationIdSuffix ".free"
versionNameSuffix "-free"
}
paid {
dimension "version"
applicationIdSuffix ".paid"
versionNameSuffix "-paid"
}
}
}
小技巧: 用 applicationIdSuffix 可以让免费版和付费版同时安装在同一台手机上,调试时特别方便。我在做内测分发时经常用这个。
二、配置不同的构建类型
2.1 构建类型的作用
构建类型不只是「能不能调试」的区别。release 版会开启混淆、压缩资源,debug 版则会保留日志输出。嗯,这里要注意:千万别把 debug 的签名配置用到 release 上,否则上架时会出问题。
| 属性 | debug | release |
|---|---|---|
| isDebuggable | true | false |
| isMinifyEnabled | false | true |
| applicationIdSuffix | .debug | (无) |
| 签名配置 | 默认 debug 签名 | 需配置 release 签名 |
2.2 为不同风味提供不同代码
你想想看,免费版和付费版肯定有些功能不一样。比如免费版有广告,付费版没有。怎么做?
在 src 目录下创建对应的源集目录:
app/src/
├── main/ # 公共代码
│ ├── java/...
│ └── res/...
├── free/ # 免费版特有
│ ├── java/com/example/myapp/
│ │ └── AdManager.java
│ └── res/...
└── paid/ # 付费版特有
├── java/com/example/myapp/
│ └── AdManager.java
└── res/...
我在一个工具类项目里,就用这种方式区分了「免费版有启动广告」和「付费版无广告」。两个 AdManager.java 实现不同逻辑,但对外接口一致。
注意: 不同风味的同名类必须放在相同的包路径下,否则编译会报「重复类」错误。我曾经因为这个排查了半天,最后发现是包名写错了。
三、在模拟器上调试
3.1 选择合适的模拟器
模拟器调试,我个人推荐用 API 33 或 34 的 Pixel 设备镜像。为什么?因为性能好、兼容性强。如果你用低版本 API,有些新特性跑不起来。
创建模拟器的步骤:
- 打开 AVD Manager(工具栏上的小手机图标)
- 点击「Create Virtual Device」
- 选择 Pixel 6 或 Pixel 7 设备
- 选择 API 34 的 System Image(建议下载 x86_64 版本)
- 设置 AVD 名称,比如「Pixel_6_API_34」
提速技巧: 在模拟器设置中开启「Use Host GPU」,图形渲染会快很多。另外,分配至少 2GB RAM 给模拟器,避免卡顿。
3.2 选择构建变体并运行
在 Android Studio 底部工具栏找到「Build Variants」面板,你会看到四个变体:
- freeDebug — 免费版调试
- freeRelease — 免费版发布
- paidDebug — 付费版调试
- paidRelease — 付费版发布
选择 freeDebug,然后点击运行按钮。Android Studio 会自动编译、安装并启动 App。如果你想同时装免费版和付费版,可以分别选择 freeDebug 和 paidDebug 各运行一次。
// 在代码中判断当前风味
if (BuildConfig.FLAVOR == "free") {
showAdBanner()
} else {
// 付费版无广告
}
为什么会这样?因为 BuildConfig.FLAVOR 会自动根据当前选中的变体生成对应的值。你不需要手动改任何代码。
3.3 调试技巧
调试时我习惯用 Log.d() 输出关键信息,而不是 System.out.println()。因为 Logcat 可以按 tag 过滤,方便定位问题。
另外,如果你发现模拟器上 App 闪退,先看看 Logcat 里有没有 ClassNotFoundException。这通常是因为某个风味下的类没被包含进来。
调试清单:
- ✅ 确认 Build Variants 面板选对了变体
- ✅ 检查 Logcat 日志级别设为 Debug
- ✅ 使用
BuildConfig.DEBUG控制调试代码 - ✅ 不同风味使用不同 applicationId,避免覆盖安装
四、完整项目结构一览
最后,我们来看一下整个项目的目录结构。这样你心里就有谱了:
MyApp/
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/com/example/myapp/
│ │ │ │ └── MainActivity.java
│ │ │ ├── res/
│ │ │ └── AndroidManifest.xml
│ │ ├── free/
│ │ │ ├── java/com/example/myapp/
│ │ │ │ └── AdManager.java
│ │ │ └── res/
│ │ │ └── drawable/
│ │ │ └── ic_launcher_free.png
│ │ └── paid/
│ │ ├── java/com/example/myapp/
│ │ │ └── AdManager.java
│ │ └── res/
│ │ └── drawable/
│ │ └── ic_launcher_paid.png
│ └── build.gradle
├── build.gradle
└── settings.gradle
说白了,多风味项目就是「一套代码,多套配置」。你只需要维护公共逻辑,差异部分交给 flavor 去处理。我在实际项目中,用这个模式同时维护了 5 个渠道版本,效率提升很明显。
最后提醒: 记得在 free 和 paid 目录下都放一个 AndroidManifest.xml(如果需要覆盖权限或 Activity 声明)。不过大多数情况下,main 里的 Manifest 就够用了。