引言
在Android开发中,我们经常会遇到各种各样的代码包格式:.a、.so、.jar、.aar、.apk、.aab等。这些格式看似相似,实则各司其职,构成了Android应用的完整开发生态。本文将带你深入理解这些代码包的区别、联系以及在实际项目中的应用。
一、代码包全景概览
让我们先用一个表格快速了解这些代码包的核心特征:
| 格式 | 全称 | 层级 | 主要用途 | 是否可安装 |
|---|---|---|---|---|
.a | Static Library | 原生开发层 | C/C++静态链接库 | ❌ |
.so | Shared Object | 原生开发层 | C/C++动态链接库 | ❌ |
.jar | Java Archive | Java字节码层 | Java/Kotlin类库 | ❌ |
.aar | Android Archive | Android组件层 | Android库模块 | ❌ |
.apk | Android Package | 应用分发层 | 应用安装包 | ✅ |
.aab | Android App Bundle | 应用发布层 | 应用发布格式 | ❌ |
二、逐层解析代码包
2.1 原生开发层
🔹 .a - 静态库文件
特点:
- 编译时直接链接到目标程序中
- 代码被复制到最终可执行文件
- 生成文件较大,但运行时无外部依赖
使用场景:
# CMakeLists.txt
add_library(native_filter STATIC native_filter.cpp)
# 输出: libnative_filter.a
🔹 .so - 动态库文件
特点:
- 运行时动态加载
- 多个进程可共享同一库文件
- 节省磁盘和内存空间
使用场景:
# CMakeLists.txt
add_library(native_filter SHARED native_filter.cpp)
# 输出: libnative_filter.so
关系:.a → 编译时链接 → .so
2.2 Java字节码层
🔹 .jar - Java归档库
内容结构:
image-utils.jar
├── META-INF/
│ └── MANIFEST.MF
├── com/example/
│ └── ImageValidator.class
└── resources/
└── config.properties
特点:
- 纯Java/Kotlin字节码
- 不包含Android资源
- 跨平台使用
2.3 Android组件层
🔹 .aar - Android归档库
内容结构:
photo-sdk.aar
├── classes.jar ← Java字节码
├── res/ ← Android资源
│ ├── layout/
│ └── drawable/
├── jni/ ← 原生库
│ ├── arm64-v8a/
│ │ └── libnative.so
├── AndroidManifest.xml ← 清单文件
└── R.txt ← 资源映射
特点:
.jar的Android增强版- 包含资源、清单文件等Android特有内容
- 支持原生库打包
与.jar的关系:.aar = .jar + Android资源 + 清单文件 + 原生库
2.4 应用分发层
🔹 .apk - Android应用包
内容结构:
app-release.apk
├── AndroidManifest.xml
├── classes.dex ← 所有Java代码
├── resources.arsc ← 编译后的资源
├── res/ ← 资源文件
└── lib/ ← 原生库
├── arm64-v8a/
│ └── libnative.so
特点:
- 最终安装包格式
- 包含应用完整内容
- 可直接安装到设备
2.5 应用发布层
🔹 .aab - Android App Bundle
特点:
- Google推出的发布格式
- 支持动态交付
- 减小应用体积
- 由Google Play生成设备特定APK
优势:
- 按设备配置分发资源
- 支持动态功能模块
- 自动优化APK大小
三、实际项目应用示例
3.1 应用架构
PhotoMagic/
├── app/ → 生成 .apk (主应用)
├── core/ → 生成 .aar (核心库)
├── image-utils/ → 生成 .jar (工具类)
├── native-filter/ → 生成 .so (原生库)
│ └── dependencies/ → 生成 .a (静态库)
└── build.gradle
3.2 依赖关系配置
// app/build.gradle
dependencies {
implementation project(':core') // .aar
implementation project(':image-utils') // .jar
implementation fileTree(dir: 'libs', include: ['*.so'])
}
// core/build.gradle
plugins {
id 'com.android.library' // 生成 .aar
}
// image-utils/build.gradle
plugins {
id 'java-library' // 生成 .jar
}
3.3 构建流程关系图
四、Multi-Module项目中的编译产出
在多模块项目中,不同模块类型会产生不同的包格式:
| Module类型 | Gradle插件 | 输出格式 | 说明 |
|---|---|---|---|
| 应用模块 | com.android.application | .apk | 主入口模块 |
| Android库 | com.android.library | .aar | 可复用组件 |
| Java库 | java-library | .jar | 纯业务逻辑 |
| Kotlin库 | org.jetbrains.kotlin.jvm | .jar | 纯Kotlin逻辑 |
五、开发实践建议
5.1 包格式选择策略
- 使用
.jar:纯业务逻辑、工具类、跨平台代码 - 使用
.aar:包含UI组件、资源、Android特定功能 - 使用
.so:高性能计算、图像处理、现有C/C++库 - 发布选择:内部测试用
.apk,商店发布用.aab
5.2 性能优化技巧
- 原生库优化:将频繁使用的代码编译为
.so - 模块化设计:使用
.aar实现功能解耦 - 资源管理:利用
.aab实现资源动态分发 - 依赖管理:合理选择
.jar和.aar依赖
六、总结
Android的代码包生态是一个层次分明、各司其职的完整体系:
- 开发阶段:使用
.a、.so、.jar、.aar进行模块化开发 - 测试阶段:生成
.apk进行功能验证 - 发布阶段:构建
.aab实现最优分发