在我们刚刚度过的 2025 年,Android 开发生态经历了前所未有的变革。当我们坐在电脑前,准备发布一款结合了 AI 代理功能的现代应用时,面对构建选项中的 "APK" 和 "AAB",你可能已经不再仅仅感到困惑,而是开始思考如何利用这些格式来最大化分发效率。这不仅仅是文件扩展名的区别,更代表了 Android 生态系统从 "静态交付" 向 "动态、智能化交付" 的巨大跨越。在这篇文章中,我们将以开发者的视角,深入探讨这两种格式背后的技术原理,剖析它们在 2026 年新环境下的工作机制,并结合最新的 Agentic AI 开发模式,帮助你做出最适合项目的技术选型。
背景:现代分发的挑战与机遇
在早期的 Android 开发中,也就是我们常说的 "前置 AI 时代",为了适配市场上成千上万种不同屏幕密度、CPU 架构(如 arm64-v8a, armeabi)和语言的设备,我们通常不得不构建一个包含所有资源的 "巨无霸" APK。这意味着,即使用户的设备只需要 1080p 的资源,他们也不得不下载包含 4K 资源的安装包。这不仅浪费了用户的流量,也增加了应用的安装门槛。
而到了 2026 年,随着应用体积的膨胀(尤其是集成了本地 LLM 推理库的应用),这种 "一刀切" 的分发方式已不可持续。我们需要一种更智能的交付方式。让我们先回顾一下我们熟悉的 APK 格式,再看看 AAB 是如何结合现代技术栈解决问题的。
什么是 APK?(Android Application Package)
APK(Android 应用程序包)依然是我们最亲密的战友。从技术上讲,一个 APK 文件本质上是一个 ZIP 归档文件。在我们的 Cursor 或 Windsurf 等 AI 辅助 IDE 中,即使代码由 AI 生成,最终的产物依然离不开这些基础组件:
- Dex 文件:包含应用程序的编译代码(Dalvik 字节码)。
- Resources.arsc:包含预编译的资源。
- res/ 目录:未编译的资源。
- AndroidManifest.xml:应用的全局描述文件。
- META-INF/ 目录:签名文件。
#### APK 的工作原理与局限
当我们构建一个传统的 "Universal APK"(通用 APK)时,构建工具会将所有可能的资源都打包进一个文件中。
代码示例 1:配置 Gradle 生成 Universal APK
虽然 AAB 是主流,但在某些需要直接分发文件的场景下,我们仍需构建 APK。
// 在 app 模块的 build.gradle 中
android {
compileSdk 35 // 使用 2026 年的最新 SDK
buildTypes {
release {
minifyEnabled true
// R8 全模式优化,结合 AI 代码混淆
proguardFiles getDefaultProguardFile(‘proguard-android-optimize.txt‘), ‘proguard-rules.pro‘
}
}
// 针对侧载或第三方商店的分发配置
splits {
abi {
enable true
reset()
include ‘x86‘, ‘armeabi-v7a‘, ‘arm64-v8a‘
universalApk true // 生成一个包含所有架构的通用 APK
}
}
}
#### APK 的局限性
APK 的局限性在 2026 年显得尤为突出。随着我们开始在应用中集成本地模型(几MB到几百MB的 .tflite 或 .gguf 文件),单一 APK 会导致安装包体积失控。如果用户只是为了体验一个简单的 AI 文本摘要功能,却被迫下载包含完整图像生成模型的 APK,这显然是不合理的。APK 格式的静态特性使其无法应对这种 "按需" 的需求。
什么是 AAB?(Android App Bundle)
AAB(Android App Bundle)自 2018 年推出以来,已成为 Google Play 的强制标准,并在 2026 年变得更加智能。它是一个发布格式,一种 "配方"。当我们将 AAB 上传到 Google Play 后,Play Store 的服务会利用这个 bundle,动态地为每一种特定的设备配置生成并签发一个优化的 APK。这个过程被称为 Dynamic Delivery(动态交付)。
#### 核心概念:Dynamic Delivery 与 Asset Delivery
AAB 的强大之处在于它支持模块化和大型资源分发。一个 AAB 项目通常包含以下部分:
- Base Module(基础模块):应用启动的核心。
- Configuration APKs(配置 APK):针对特定屏幕、架构、语言的优化。
- Dynamic Feature Modules(动态功能模块):按需下载的功能。
- Asset Packs(资源包):这是 2026 年游戏和 AI 应用的关键,允许将庞大的资源文件独立于 APK 交付。
代码示例 2:使用 Play Asset Delivery 管理 AI 模型文件
在我们的项目中,经常需要处理大型文件。比如,我们要集成一个本地运行的 Llama 3 模型。我们绝不能把这个模型打包在 APK 或 Base Module 中。最佳实践是使用 Asset Delivery 的 "On-Delivery" 模式。
假设我们有一个 500MB 的模型文件放在 src/main/assets/model_folder 中。
首先,创建一个 Asset Pack:
// 在 asset-pack 模块的 build.gradle 中
apply plugin: ‘com.android.asset-pack‘
assetPack {
packName = "llm_model_pack" // 目录名称
dynamicDelivery {
deliveryType = "on-demand" // 按需下载
}
}
然后,在 Base Module 的 build.gradle 中链接它:
android {
assetPacks = [":llm_model_pack"]
}
PK 详解:APK 与 AAB 在 2026 的差异与选择
既然我们已经了解了技术原理,让我们结合 2026 年的开发场景来对比这两种格式。
#### 1. 大型资源与 AI 模型的分发
- APK: 处理大型资源极其痛苦。如果应用超过 150MB(不同商店限制不同),甚至无法上传。为了更新一个模型参数,你需要重新发布整个 APK。
- AAB: 支持 Play Asset Delivery。我们可以将 AI 模型、高清纹理包独立存放。当用户点击 "启用 AI 助手" 时,应用才在后台下载 500MB 的模型包。这在 APK 模式下需要手动编写复杂的下载器和文件管理器,且极易出错。
#### 2. 动态功能交付
这是 AAB 区别于 APK 的核心能力。让我们看看如何在代码中请求下载一个动态功能模块,例如一个 "高级图像生成" 功能。
代码示例 3:在运行时请求下载动态功能模块(Kotlin 版本)
这是我们在生产环境中使用的标准逻辑,结合了 Kotlin 协程和现代化的错误处理。
import com.google.android.play.core.ktx.activityResultRegistry
import com.google.android.play.core.splitinstall.*
import com.google.android.play.core.splitinstall.model.SplitInstallSessionState
import com.google.android.play.core.splitinstall.testing.TestSplitInstallManager
import java.util.util
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
class FeatureDeliveryManager(private val activity: Activity) {
private val splitInstallManager = SplitInstallManagerFactory.create(activity)
// 使用 Flow 封装回调,符合 2026 年的响应式编程范式
fun downloadFeature(moduleName: String) = callbackFlow {
if (splitInstallManager.installedModules.contains(moduleName)) {
trySend(SplitInstallState.Success(moduleName))
awaitClose()
return@callbackFlow
}
val request = SplitInstallRequest.newBuilder()
.addModule(moduleName)
.build()
// 注册监听器
val listener = SplitInstallStateUpdatedListener { state ->
when (state.status()) {
SplitInstallSessionStatus.DOWNLOADING -> {
// 更新 UI 下载进度: ${state.bytesDownloaded() / state.totalBytesToDownload()}%")
}
SplitInstallSessionStatus.INSTALLED -> {
// 关键:对于动态功能模块,需要处理 SplitCompat
SplitCompat.installActivity(activity)
trySend(SplitInstallState.Success(moduleName))
}
SplitInstallSessionStatus.FAILED -> {
trySend(SplitInstallState.Error("Error: ${state.errorCode()}"))
}
}
}
splitInstallManager.registerListener(listener)
splitInstallManager.startInstall(request)
awaitClose {
splitInstallManager.unregisterListener(listener)
}
}
}
这种 "按需下载" 的能力在 APK 模式下几乎无法原生实现,通常需要自行编写复杂的插件化加载框架(如 RePlugin 或 VirtualApk),但在面对 Android 12+ 的隐私限制和更加严苛的运行时权限时,这些第三方框架的维护成本极高。
#### 3. AI 辅助开发与调试流程
在我们的日常开发中,利用 AI IDE(如 Cursor)可以极大地加速 AAB 的调试流程。当我们在 IDE 中输入提示词:"生成一个使用 bundletool 测试 AAB 的脚本",我们可以得到如下工作流。
代码示例 4:使用 Bundle Tool 进行本地化测试
在发布到 Play Store 之前,我们必须验证 Dynamic Delivery 是否工作。
# 1. 构建 APKs 集合(模拟 Play Store)
# 注意:你需要下载 bundletool-all.jar
bundletool build-apks --bundle=./app/build/outputs/bundle/release/app-release.aab \
--output=./app.apks \
--ks=./keystore.jks \
--ks-pass=pass:password \
--ks-key-alias=key0 \
--key-pass=pass:password
# 2. 部署到连接的设备
# 这一步会根据你的设备(例如 Pixel 6)生成并安装最优化的 APK
bundletool install-apks --apks=./app.apks
# 3. 模拟特定配置(强制安装特定模块)
bundletool extract-apks \
--apks=./app.apks \
--output-dir=./extracted_apks \
--instant \
--device-spec=device-spec.json
我们通常会让 AI 生成不同设备规格的 device-spec.json,以此来模拟低端设备或平板电脑的安装包情况。
2026 年深度对比表
AAB (App Bundle)
:—
现代发布格式,AI 时代的 "Recipe"。
动态拆分。支持代码、资源、Asset 的按需交付。
Google Play 及支持 AAB 的主流商店;AI 应用分发。
极高。针对屏幕、ABI、语言、用户层级优化。
原生支持。结合 Play Core 库,用户体验流畅。
Play Asset Delivery。专为大型模型和贴图设计。
常见错误与解决方案(基于 2026 年实战经验)
在从 APK 迁移到 AAB 的过程中,我们踩过不少坑。以下是我们的总结。
- SplitCompat 遗忘症:
* 问题:下载了动态功能模块后,应用直接崩溃,提示 ClassNotFoundException。
* 解决:这是最经典的错误。在动态模块安装后,必须通知 Context 加载新的代码。除了在 INLINECODEb5db230b 类中安装,对于 Activity,强烈推荐使用 INLINECODE1e3355e2,或者在 AndroidManifest 中为所有 Activity 声明 INLINECODEb3d9ce66SplitInstallManager.registerListenerINLINECODEf8ca5989splitInstallManager.getSessionStates()INLINECODE3632be76AssetManagerINLINECODEa9ead356.apk` 文件依然是分享开源软件的标准方式。
我们的最终建议策略是:
在 CI/CD 流水线中,将 AAB 作为 Release Artifact 的标准产出。利用 GitHub Actions 或 Jenkins 自动构建并上传到 Google Play。同时,保留一个生成 "Universal APK" 的任务,专门用于分发到 TestFlight(虽然那是 iOS 的,但在 Android 侧对应的是各类 Beta 平台)或内部测试群。在开发阶段,继续享受 APK 带来的极速部署体验。拥抱 AAB,就是拥抱 Android 生态更高效、更智能的未来。