跳到主要内容

AGP 与 Build Variant

问题

Android Gradle Plugin (AGP) 是什么?Build Variant 如何组合?

答案

AGP 的作用

AGP 扩展了 Gradle,提供 Android 特有的构建能力:

  • 编译 Android 资源(AAPT2)
  • 管理 Build Type / Product Flavor / Build Variant
  • 生成 BuildConfigR
  • 签名、混淆、打包 APK/AAB
  • Lint 检查

Build Variant = Build Type × Product Flavor

配置示例

app/build.gradle.kts
android {
buildTypes {
debug {
isDebuggable = true
applicationIdSuffix = ".debug"
// debug 包可与 release 共存
}
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}

flavorDimensions += "version"
productFlavors {
create("free") {
dimension = "version"
applicationIdSuffix = ".free"
buildConfigField("boolean", "IS_PRO", "false")
}
create("pro") {
dimension = "version"
applicationIdSuffix = ".pro"
buildConfigField("boolean", "IS_PRO", "true")
}
}
}

源集(Source Set)

每个 Variant 可以有独立的源代码和资源目录:

app/src/
├── main/ # 所有 Variant 共享
├── debug/ # debug Build Type 专属
├── release/ # release Build Type 专属
├── free/ # free Flavor 专属
├── pro/ # pro Flavor 专属
├── freeDebug/ # freeDebug Variant 专属
└── proRelease/ # proRelease Variant 专属

合并优先级:Variant > Build Type > Flavor > main

BuildConfig

app/build.gradle.kts
android {
defaultConfig {
buildConfigField("String", "API_URL", "\"https://api.example.com\"")
}
buildTypes {
debug {
buildConfigField("String", "API_URL", "\"https://dev.example.com\"")
}
}
}
使用生成的 BuildConfig
if (BuildConfig.DEBUG) {
// debug 专属逻辑
}
val url = BuildConfig.API_URL
AGP 8.0+ 变化

AGP 8.0 起 BuildConfig 默认关闭,需手动开启:

android {
buildFeatures {
buildConfig = true
}
}

常见面试问题

Q1: Build Type 和 Product Flavor 的区别?

答案

维度Build TypeProduct Flavor
用途区分构建配置(debug/release)区分产品版本(免费/付费、国内/海外)
默认值debug + release无默认值
可配置项debuggable、minifyEnabled、签名applicationId、versionCode、资源
数量限制至少有一个可以没有

两者通过笛卡尔积组合生成最终的 Build Variant。

Q2: 如何在不同 Flavor 中使用不同的依赖?

答案

使用 Flavor 名称作为依赖配置的前缀:

dependencies {
// 仅 free 版包含广告 SDK
"freeImplementation"("com.google.ads:sdk:21.0.0")
// 仅 pro 版包含高级功能库
"proImplementation"("com.example:premium-features:1.0.0")
}

同理可以在 src/free/src/pro/ 下放置各自的源代码,实现功能差异。

相关链接