一、APK 是什么?
APK(Android Package Kit)是Android操作系统使用的应用程序包文件格式。它本质上是一个ZIP压缩文件 ,使用**.apk
**作为扩展名。你可以直接使用任何解压缩软件(如WinRAR、7-Zip)打开它并查看里面的内容。
它的主要作用是将开发好的Android应用的所有必要资源打包在一起,便于分发和安装。
二、APK 里面有哪些核心内容
解压一个APK文件后,你会看到类似下图的文件结构,其核心组件与构建流程密切相关:

下面我们对这些核心组件进行详细说明:
1. AndroidManifest.xml
(应用配置清单)
-
是什么? :这是APK的总配置文件 ,但它不是纯文本的XML,而是被Android构建工具(AAPT2)编译成了二进制格式,以节省空间和加快解析速度。
-
包含什么?:
-
应用的包名、版本号、版本名称。
-
应用包含的所有组件(Activity、Service、BroadcastReceiver、ContentProvider)。
-
应用申请的系统权限。
-
应用所需的最低/目标Android版本。
-
声明其所使用的硬件/软件特性(如需要摄像头)。
-
2. classes.dex
(代码文件)
-
是什么? :这是Android系统的可执行字节码文件 。Java或Kotlin源代码首先被编译成标准的JVM
.class
文件,然后通过Android SDK的dx
或d8
工具将所有这些.class
文件优化、合并成一个或多个classes.dex
文件(如果方法数超过65536的限制,会产生classes2.dex
,classes3.dex
等)。 -
为什么是dex?:DEX(Dalvik Executable)格式专为Android设计,针对内存有限和处理器速度较慢的移动设备进行了优化。
3. resources.arsc
(资源映射表)
-
是什么? :这是一个编译后的资源索引表。它同样是由AAPT2工具生成的二进制文件。
-
为什么需要它? :为了高效地根据设备的当前配置(如语言、屏幕密度、横竖屏)快速定位到最合适的资源。它建立了"资源ID"(你在代码中用的
R.drawable.icon
)和"资源文件路径"(res/drawable-hdpi/icon.png
)之间的映射关系。
4. res/
目录 (资源文件)
-
是什么? :包含未被编译到
resources.arsc
中的原始资源文件 。注意,这里的布局文件(.xml
)已经被编译成了二进制格式,不再是纯文本。 -
包含什么?:
-
drawable-*/
,mipmap-*/
:图片资源(PNG, JPG, WebP)和矢量图(XML)。 -
layout/
:UI布局文件。 -
values/
:字符串(strings.xml
)、颜色(colors.xml
)、尺寸(dimens.xml
)等。 -
anim/
,raw/
,xml/
等其它资源目录。
-
5. assets/
目录 (资产文件)
-
是什么? :与
res/
目录不同,这里的文件会保持原样 打包进APK,不会 被编译,也不会被生成资源ID。 -
如何访问? :只能通过
AssetManager
类以流的方式读取(getAssets().open("filename")
)。 -
用途:存放游戏数据包、字体文件、配置文件等需要保持原始结构的资源。
6. lib/
目录 (原生库)
-
是什么? :包含应用程序使用的原生代码库 (通常用C/C++编写),编译为
.so
(shared object)文件。 -
子目录:按不同的CPU架构分包,如:
-
armeabi-v7a
:针对32位ARM处理器。 -
arm64-v8a
:针对64位ARM处理器(当前主流)。 -
x86_64
,x86
:针对Intel处理器(常用于模拟器)。
-
7. META-INF/
目录 (元信息/签名)
-
是什么? :该目录包含APK的签名和验证信息,以确保APK的完整性和来源可信。
-
包含什么?:
-
MANIFEST.MF
:列出APK中所有文件的名称及其SHA-1摘要。 -
CERT.SF
:对MANIFEST.MF
文件的摘要进行签名。 -
CERT.RSA
:包含签名证书和对CERT.SF
文件的数字签名。
-
8. resources.pb
(新版资源表)
- 是什么? :在使用新版本的构建工具(如AAPT2)后,资源编译的输出不再是单一的
resources.arsc
,而是会包含一个resources.pb
文件(Protocol Buffer格式),它与resources.arsc
共同工作,存储编译后的资源信息。
三、常见问题总结
Q:"一个Android APK文件里面主要包含哪些内容?"
A:
APK本质上是一个ZIP压缩包,它包含了Android应用安装和运行所需的所有文件。主要的核心内容有以下几个:
-
AndroidManifest.xml
:这是应用的总配置文件,声明了包名、组件、权限等信息,但它被编译成了二进制格式。 -
classes.dex
:这是Android系统的可执行字节码文件 ,由Java/Kotlin源码编译后转换而成,是应用的代码核心。如果方法数超限,还会有classes2.dex
。 -
resources.arsc
:这是编译后的资源索引表,它是一个二进制文件,建立了资源ID到资源路径的映射关系,用于系统高效地加载适合当前设备配置的资源。 -
res/
目录 :存放编译后的资源文件,如图片、布局、字符串等。注意,这里的XML布局文件也被编译成了二进制格式。 -
assets/
目录 :存放原始资产文件 ,不会被编译,只能通过AssetManager
以流的方式读取。 -
lib/
目录 :存放应用依赖的C/C++原生库(.so文件),按CPU架构(如arm64-v8a)分包。 -
META-INF/
目录 :包含APK的签名信息,用于验证APK的完整性和发布者身份。
此外,在新版本的构建工具下,还可能看到 resources.pb
文件,它和 resources.arsc
一起负责资源管理。
Q:"APK 和 AAR 看起来很相似,它们有什么区别?"
A:
APK vs AAR 详细对比
特性 | AAR (Android Archive) | APK (Android Application Package) |
---|---|---|
本质 | 库模块的发布包(中间产物) | 应用的发布包(最终产物) |
目的 | 被依赖 、被集成到其他应用或模块中 | 被安装 到Android设备上独立运行 |
包含的清单文件 | AndroidManifest.xml 可能是不完整的 ,通常只声明组件和权限,版本号等信息常被忽略 |
必须包含一个完整且有效的 AndroidManifest.xml ,用于安装和运行 |
代码文件 | classes.jar (需要再次编译,汇入主项目的DEX中) |
classes.dex (已编译完成,可直接被Android运行时执行) |
资源文件 | 包含 /res/ , /assets/ 供合并到主项目 |
包含 已合并并编译优化后 的 /res/ , /assets/ |
资源索引表 | 通常不包含最终版的 resources.arsc |
必须包含 最终版的 resources.arsc |
签名 | 不需要签名 | 必须被签名(调试或发布签名),否则无法安装 |
原生库 | 包含 /jni/ 目录下的 .so 文件 |
包含已按ABI分包到 /lib/ 目录下的 .so 文件 |
生成的Gradle任务 | bundle**Release**Aar / assemble**Release** |
assemble**Release** |
安装 | 无法安装到设备上 | 可以安装到设备上运行 |
AAR 是 Android 库的分发格式 ,是一个中间产物 。它像是应用的一个'零部件',目的是被依赖和集成到主应用模块中。因此,它的内容(如 classes.jar
)还需要参与主应用的最终编译,它本身不需要签名 ,也无法直接安装到设备上运行。
而 APK 是 Android 应用的安装包 ,是最终产物 。它像是'组装好的整车',包含了所有必需的零部件(AAR/JAR)、合并后的资源、完整的清单文件,并且必须经过签名,才能被安装到设备上独立运行。
简单总结就是:AAR 用于模块化开发和代码复用,而 APK 用于分发和安装应用。 我们在构建过程中,会将多个 AAR '零部件'组装并加工成最终的 APK '整车'。"