深入理解Android代码包:.a、.so、.jar、.aar、.apk、.aab

111 阅读3分钟

引言

在Android开发中,我们经常会遇到各种各样的代码包格式:.a.so.jar.aar.apk.aab等。这些格式看似相似,实则各司其职,构成了Android应用的完整开发生态。本文将带你深入理解这些代码包的区别、联系以及在实际项目中的应用。

一、代码包全景概览

让我们先用一个表格快速了解这些代码包的核心特征:

格式全称层级主要用途是否可安装
.aStatic Library原生开发层C/C++静态链接库
.soShared Object原生开发层C/C++动态链接库
.jarJava ArchiveJava字节码层Java/Kotlin类库
.aarAndroid ArchiveAndroid组件层Android库模块
.apkAndroid Package应用分发层应用安装包
.aabAndroid 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 构建流程关系图

image.png

四、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 性能优化技巧

  1. 原生库优化:将频繁使用的代码编译为.so
  2. 模块化设计:使用.aar实现功能解耦
  3. 资源管理:利用.aab实现资源动态分发
  4. 依赖管理:合理选择.jar.aar依赖

六、总结

Android的代码包生态是一个层次分明、各司其职的完整体系:

  • 开发阶段:使用.a.so.jar.aar进行模块化开发
  • 测试阶段:生成.apk进行功能验证
  • 发布阶段:构建.aab实现最优分发