Android中APK包含哪些内容?

一、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的 dxd8 工具将所有这些 .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应用安装和运行所需的所有文件。主要的核心内容有以下几个:

  1. AndroidManifest.xml :这是应用的总配置文件,声明了包名、组件、权限等信息,但它被编译成了二进制格式。

  2. classes.dex :这是Android系统的可执行字节码文件 ,由Java/Kotlin源码编译后转换而成,是应用的代码核心。如果方法数超限,还会有 classes2.dex

  3. resources.arsc :这是编译后的资源索引表,它是一个二进制文件,建立了资源ID到资源路径的映射关系,用于系统高效地加载适合当前设备配置的资源。

  4. res/ 目录 :存放编译后的资源文件,如图片、布局、字符串等。注意,这里的XML布局文件也被编译成了二进制格式。

  5. assets/ 目录 :存放原始资产文件 ,不会被编译,只能通过 AssetManager 以流的方式读取。

  6. lib/ 目录 :存放应用依赖的C/C++原生库(.so文件),按CPU架构(如arm64-v8a)分包。

  7. 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 '整车'。"

相关推荐
阿巴斯甜8 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker9 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952710 小时前
Andorid Google 登录接入文档
android
黄林晴11 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android