AAB 构建与发布
源:Android 官方文档 - 关于 Android App Bundle
Android App Bundle (AAB) 是 Android 的官方发布格式,相比传统 APK 有更小的下载体积和更灵活的分发方式。
AAB 简介
什么是 AAB
AAB 是一种发布格式,包含应用的所有编译代码和资源,但将 APK 生成和签名交给 Google Play。
AAB vs APK
APK(传统):
- 单一文件包含所有资源和代码
- 体积大(包含所有语言、所有分辨率资源)
- 用户下载完整 APK
AAB(推荐):
- 仅发布时使用的格式
- Google Play 根据设备生成优化的 APK
- 用户仅下载设备需要的资源
- 平均减少 15% 下载体积
AAB 的优势
更小的下载体积:
- 仅包含设备需要的代码和资源
- 自动进行语言、屏幕密度、ABI 拆分
Dynamic Feature Modules:
- 按需下载功能模块
- 减少初始安装体积
Asset Packs:
- 延迟下载大型资源(如游戏关卡)
- 支持最大 2GB 的资源包
自动优化:
- Google Play 自动应用最新优化技术
- 无需更新应用即可获得优化
构建 AAB
使用 Android Studio
Build → Generate Signed Bundle / APK → 选择 Android App Bundle
使用 Gradle
bash
# 构建 release AAB
./gradlew bundleRelease
# 构建其他变体
./gradlew bundleDebug
./gradlew bundleDemoRelease输出位置:
app/build/outputs/bundle/release/app-release.aab配置混淆
AAB 同样需要 ProGuard/R8 配置:
kotlin
android {
buildTypes {
getByName("release") {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}配置语言和密度拆分
虽然 Google Play 会自动拆分,但可以配置默认拆分行为:
kotlin
android {
bundle {
language {
// 禁用语言拆分(不推荐)
enableSplit = false
}
density {
// 禁用密度拆分(不推荐)
enableSplit = false
}
abi {
// 启用 ABI 拆分(默认启用)
enableSplit = true
}
}
}本地测试 AAB
使用 bundletool
bundletool 是官方命令行工具,用于从 AAB 生成 APK:
安装 bundletool:
下载最新版本:https://github.com/google/bundletool/releases
生成 APK Sets:
bash
java -jar bundletool.jar build-apks \
--bundle=app-release.aab \
--output=app-release.apks \
--ks=keystore.jks \
--ks-key-alias=key-alias安装到设备:
bash
# 安装适合连接设备的 APK
java -jar bundletool.jar install-apks \
--apks=app-release.apks提取特定配置的 APK:
bash
# 提取中文 xxhdpi arm64 的 APK
java -jar bundletool.jar extract-apks \
--apks=app-release.apks \
--output-dir=output/ \
--device-spec=device-spec.json创建设备规范文件
device-spec.json:
json
{
"supportedAbis": ["arm64-v8a"],
"supportedLocales": ["zh"],
"screenDensity": 480,
"sdkVersion": 30
}上传到 Google Play
Play Console 上传
- 登录 Google Play Console
- 选择应用
- 发布 → 生产版本(或其他轨道)
- 创建新版本
- 上传 AAB 文件
- 填写版本信息
- 审核并发布
使用 Gradle Play Publisher
自动化发布流程:
kotlin
plugins {
id("com.github.triplet.play") version "3.9.0"
}
play {
serviceAccountCredentials.set(file("service-account-key.json"))
track.set("internal") // internal, alpha, beta, production
defaultToAppBundles.set(true)
}发布:
bash
./gradlew publishReleaseBundleDynamic Feature Modules
创建 Dynamic Feature 模块
File → New → New Module → Dynamic Feature Module
配置依赖
在 app 模块:
kotlin
// app/build.gradle.kts
android {
dynamicFeatures += setOf(":feature_camera", ":feature_gallery")
}在 feature 模块:
kotlin
// feature_camera/build.gradle.kts
plugins {
id("com.android.dynamic-feature")
}
android {
namespace = "com.example.feature.camera"
}
dependencies {
implementation(project(":app"))
}按需加载
kotlin
val splitInstallManager = SplitInstallManagerFactory.create(context)
val request = SplitInstallRequest.newBuilder()
.addModule("feature_camera")
.build()
splitInstallManager.startInstall(request)
.addOnSuccessListener { sessionId ->
// 开始下载
}
.addOnFailureListener { exception ->
// 下载失败
}下载体积限制
压缩下载大小限制:
- 基础 APK + 配置 APK:150MB
- 基础 + 所有 Dynamic Features:150MB
解决方案:
- 使用 Asset Packs 存储大型资源
- 将功能拆分为 Dynamic Feature
- 优化资源(WebP、矢量图)
最佳实践
始终使用 AAB:
- Google Play 已强制要求新应用使用 AAB
- 不要继续使用 APK
测试所有配置:
- 使用 bundletool 测试不同设备配置
- 检查拆分后的 APK 大小
合理使用 Dynamic Features:
- 仅在功能确实可选时使用
- 避免过度拆分(影响用户体验)
保留 mapping 文件:
- AAB 同样需要 ProGuard mapping
- 每个版本保存 mapping.txt
监控下载大小:
- Play Console 提供下载大小报告
- 定期检查优化效果