Android APK组成编译打包流程详解
Android APK(Android Package)是 Android 应用的安装包文件,其组成和打包流程涉及多个步骤和文件结构。以下是详细的说明:
一、APK 的组成

APK 是一个 ZIP 格式的压缩包,包含应用运行所需的所有文件。解压后主要包含以下内容:
-
classes.dex-
由 Java/Kotlin 代码编译后的 Dalvik/ART 字节码文件。
-
如果方法数超过 65536,会生成多个
classes2.dex、classes3.dex等(需启用 MultiDex)。
-
-
resources.arsc-
编译后的二进制资源索引表,包含字符串、布局、颜色等资源的映射关系,用于快速查找资源。
-
-
AndroidManifest.xml-
应用的配置文件(二进制格式),声明包名、权限、组件(Activity/Service 等)、最低 SDK 版本等。
-
-
res/目录-
存放编译后的资源文件(图片、布局 XML、动画等),原始 XML 会被编译为二进制格式以优化读取效率。
-
-
assets/目录-
存放原始资源文件(如字体、配置文件),通过
AssetManager直接访问,不参与资源 ID 生成。
-
-
lib/目录-
存放原生库(
.so文件),按 CPU 架构分目录(如armeabi-v7a,arm64-v8a,x86)。
-
-
META-INF/目录-
包含应用签名信息(
MANIFEST.MF,CERT.SF,CERT.RSA),用于验证 APK 完整性。
-
-
kotlin/目录-
如果使用 Kotlin,会包含 Kotlin 标准库的相关文件。
-
-
其他文件
-
如 ProGuard/R8 生成的映射文件(
mapping.txt)、AAPT2 生成的资源映射等。
-
二、APK 打包流程

Android 应用的构建流程通过 Gradle 和 Android 构建工具链(如 AAPT2、D8、R8 等)完成,主要步骤如下:
1. 资源处理
-
工具:AAPT2 (Android Asset Packaging Tool)
-
编译
res/下的资源文件(XML、图片等),生成resources.arsc和二进制 XML。 -
生成
R.java文件,为每个资源分配唯一 ID。
-
2. 代码编译
-
Java/Kotlin 编译
-
将 Java/Kotlin 源代码编译为
.class文件(javac或kotlinc)。
-
-
DEX 转换
-
使用 D8 或 R8 工具 将
.class文件转换为 Android 虚拟机所需的.dex文件,优化字节码并可能启用代码混淆(通过 R8)。
-
3. 资源与代码合并
-
工具:Android Gradle Plugin
-
合并所有模块的资源文件,处理资源冲突。
-
将
classes.dex、resources.arsc、lib/、assets/等文件打包到临时 APK 中。
-
4. 原生库处理
-
将 JNI 库(
.so文件)按 CPU 架构分类,并打包到 APK 的lib/目录。
5. APK 签名
-
工具:
apksigner或jarsigner-
使用开发者密钥对 APK 进行签名,确保应用来源可信且未被篡改。
-
生成
META-INF/目录下的签名文件。
-
6. APK 对齐优化
-
工具:
zipalign-
对 APK 中的未压缩文件进行内存对齐(4 字节边界),提升运行时加载效率。
-
zipalign 主要工作是将apk包进行对齐处理。使apk包中的所有资源文件,起始偏移为4字节的整数倍,这样通过mmap内存映射访问apk时的速度会更快。
-
| 工具名称 | 功能介绍 | 在操作系统中的路径 |
|---|---|---|
| aapt | Android资源打包工具 | ${ANDROID_SDK_HOME}/build-tools/30.0.0/aapt |
| aidl | Android接口描述语言转化为.java文件的工具 | ${ANDROID_SDK_HOME}/build-tools/30.0.0/aidl |
| javac | java Compiler java代码转class文件 | ${JDK_HOME}/javac或/usr/bin/javac |
| dex | 转化.class文件为Davik VM能识别的.dex文件 | ${ANDROID_SDK_HOME}/build-tools/30.0.0/dx |
| apkbuilder | 生成apk包 | ???没有找到 |
| jarsigner | .jar文件的签名工具 | ${JDK_HOME}/jarsigner或/usr/bin/jarsigner |
| zipalign | 字节码对齐工具 | ${ANDROID_SDK_HOME}/tools/zipalign |
三、详细构建流程图
源代码 (Java/Kotlin) --> 编译 --> .class 文件 --> D8/R8 --> classes.dex
资源文件 (res/, assets/) --> AAPT2 --> resources.arsc + 二进制 XML
原生库 (JNI) --> 按架构分类打包到 lib/
合并所有文件 --> 未签名 APK --> 签名 --> 签名后的 APK --> zipalign 对齐 --> 最终 APK
四、构建工具链演进
-
AAPT → AAPT2:支持增量资源编译,提升构建速度。
-
DX → D8:更快的 DEX 编译,更好的字节码优化。
-
ProGuard → R8:将代码压缩(Shrinking)、优化(Optimization)、混淆(Obfuscation)与 DEX 编译合并为一步。
五、优化与扩展
-
Android App Bundle (AAB):Google 推出的动态分发格式,按设备配置生成优化后的 APK。
-
Split APKs:根据屏幕密度、ABI 等拆分 APK,减少用户下载体积。
-
资源混淆:通过工具(如 AndResGuard)对资源文件名进行混淆,进一步缩减 APK 体积。
六、虚拟机演进
虚拟机是一个可以运行 class , odex , oat 可执行文件的运行环境 ;
常见的虚拟机有 Java 虚拟机、Dalvik 虚拟机 、 ART 虚拟机 ;
Java 虚拟机 : 运行的 class 字节码文件 , 运行程序时解码 class 文件中的内容 ; 基于栈架构 , 需要频繁在栈上读写数据 , 造成较多的指令分派 , 更多的内存访问次数 , 比较耗费 CPU 时间 ;
编译时 : Java 源码 , 使用 javac 编译器 , 编译成 class 字节码文件 ; 运行时 : 类加载器通过 Java 类库验证字节码 , 验证通过会后进入 Java 虚拟机 , 进入 Java 解释器 或 即时编译器 , 然后进入运行时系统 , 之后进入操作系统 , 然后调用硬件 ;
Dalvik 虚拟机 : 基于 JIT 机制 ( 即时编译技术 )
Android 5.0 以下使用的虚拟机是 Dalvik 虚拟机 , 该虚拟机的可执行文件是 dex 文件 , 该文件比 class 字节码文件更小 ; JIT ( Just In Time ) 即时编译技术 , 对应 Dalvik 虚拟机 ; 基于寄存器架构 , 通过寄存器间接访问数据 , 该方式比基于栈架构速度更快 ;
ART 虚拟机 :
Android 5.0 以上使用的虚拟机是 ART 虚拟机 ; AOT ( Ahhead Of Time ) 预编译技术 , 对应 ART 虚拟机 ; Java 虚拟机 / Dalvik 虚拟机 / ART 虚拟机 都向上层提供了 3 个接口JNI_GetDefaultJavaVMInitArgs JNI_CreateJavaVM JNI_GetCreatedJavaVMS ; 虚拟机之间可实现无缝衔接 ;
Dalvik 虚拟机 与 ART 虚拟机区别 : 虚拟机中有个 persist.sys.dvlvik.vm.lib 字段 , 如果该字段存储的是 libdvm.so , 该虚拟机是 Dalvik 虚拟机 ; 如果该字段存储的是 ;ibart.so , 该虚拟机是 ART 虚拟机 ;
Dalvik 虚拟机 与 ART 虚拟机可执行文件 :
Dalvik 虚拟机加载 dex 文件加载时不是直接加载 dex 文件 , 加载执行的是 odex 文件 , odex 文件是通过 dexopt 工具对 dex 进行优化生成的 ;
ART 虚拟机加载 dex 文件时加载的是 oat 文件 , oat 文件时通过 dex2oat 工具对 dex 文件进行优化生成的 ;
通过理解 APK 的组成和打包流程,开发者可以更好地优化应用性能、调试构建问题,并掌握高级构建技术(如模块化、动态交付)。
参考:
1. 深入详解Apk编译打包流程
2. APK 打包流程 ( 文件结构 | 打包流程 | 安装流程 | 安卓虚拟机 )
3. Android 打包流程
相关文章:
Android APK组成编译打包流程详解
Android APK(Android Package)是 Android 应用的安装包文件,其组成和打包流程涉及多个步骤和文件结构。以下是详细的说明: 一、APK 的组成 APK 是一个 ZIP 格式的压缩包,包含应用运行所需的所有文件。解压后主要包含以…...
TCP长连接与短连接
TCP长连接与短连接 TCP(传输控制协议)中的长连接和短连接是两种不同的连接管理方式,各有优缺点: 短连接 短连接是指客户端与服务器完成一次数据交换后就断开连接。下次需要通信时,再重新建立连接。 特点࿱…...
C#委托(delegate)的常用方式
C# 中委托的常用方式,包括委托的定义、实例化、不同的赋值方式以及匿名委托的使用。 委托的定义 // 委托的核心是跟委托的函数结构一样 public delegate string SayHello(string c);public delegate string SayHello(string c);:定义了一个公共委托类型 …...
C#从入门到精通(35)—如何防止winform程序因为误操作被关闭
前言: 大家好,我是上位机马工,硕士毕业4年年入40万,目前在一家自动化公司担任软件经理,从事C#上位机软件开发8年以上!我们在开发的上位机软件运行起来以后,一般在右上角都有一个关闭按钮,正常情况下点击关闭按钮就能关闭软件,但是不排除我们不想关闭软件,但是因为不…...
docker本地镜像源搭建
最近Deepseek大火后,接到任务就是帮客户装Dify,每次都头大,因为docker源不能用,实在没办法,只好自己搭要给本地源。话不多说具体如下: 1、更改docker的配置文件,添加自己的私库地址,…...
Sqlserver安全篇之_TLS的证书概念
证书的理解 参考Sqlserver的官方文档https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/certificate-overview?viewsql-server-ver16 TLS(Transport Layer Security)传输层安全和SSL(Secure Sockets Layer)安全套接字层协议位于应用程序协议层和TCP/…...
Kafka生产者相关
windows中kafka集群部署示例-CSDN博客 先启动集群或者单机也OK 引入依赖 <dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>3.9.0</version></dependency>关于主题创建 理论…...
技术问题汇总:前端怎么往后端传一个数组?
场景 现在一个专门负责复习算法的服务,筛选出了用户今天需要复习的笔记的ids,现在要调用笔记服务根据ids查询的接口。 请问复习服务怎么将ids发到笔记服务,笔记服务怎么接收。 思路 发的时候肯定是用字符串,接收的时候…...
【03】STM32F407 HAL 库框架设计学习
【03】STM32F407 HAL 库框架设计学习 摘要 本文旨在为初学者提供一个关于STM32F407微控制器HAL(Hardware Abstraction Layer)库框架设计的详细学习教程。通过本文,读者将从零开始,逐步掌握STM32F407的基本知识、HAL库的配置步骤…...
智能图像处理平台:图像处理配置类
这里我们先修改一下依赖,不用JavaCV,用openCV。 导入依赖: <!-- JavaCV 依赖,用于图像和视频处理 --> <!-- <dependency>--> <!-- <groupId>org.bytedeco</groupId>--> &l…...
【图文详解】什么是微服务?什么是SpringCloud?
目录 一.认识微服务架构 ??微服务带来的挑战 二.微服务解决方案SpringCloud ??SpringCloud的版本 ??SpringCloud和SpringBoot的关系 ??SpringCloud实现方案 Spring Cloud Netfix Spring Cloud Alibaba ??Spring Cloud 实现对比 在入门Spring Cloud 之前&…...
基于ssm的校园跑腿管理系统+vue
作者主页:舒克日记 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统共有管理员、用户两个角色 管理员主要的功能用户信息管理、任务信息管理、任务类型管理、接单信息管理、公告信息管理、投诉信息管理、公告类型管…...
5个GitHub热点开源项目!!
1.自托管 Moonlight 游戏串流服务:Sunshine 主语言:C,Star:14.4k,周增长:500 这是一个自托管的 Moonlight 游戏串流服务器端项目,支持所有 Moonlight 客户端。用户可以在自己电脑上搭建一个游戏…...
docker通用技术介绍
docker通用技术介绍 1.docker介绍 1.1 基本概念 docker是一个开源的容器化平台,用于快速构建、打包、部署和运行应用程序。它通过容器化技术将应用及其依赖环境(如代码、库、系统工具等)打包成一个标准化、轻量级的独立单元,实…...
#渗透测试#批量漏洞挖掘#某图创图书馆集群管理系统updOpuserPw SQL注入(CVE-2021-44321)
免责声明 本教程仅为合法的教学目的而准备,严禁用于任何形式的违法犯罪活动及其他商业行为,在使用本教程前,您应确保该行为符合当地的法律法规,继续阅读即表示您需自行承担所有操作的后果,如有异议,请立即停…...
智能合约安全 | 合约无效化攻击
目录: 智能合约安全 合约无效化攻击 合约自毁函数 selfdestruct 攻击实现 漏洞防御 总结 智能合约安全 合约无效化攻击 合约无效化攻击类同于web安全中的逻辑漏洞中的一种 我们这里拿一个典型的例子来讲解 有这样一份智能合约, 每个人可以向其中发送1 eth 第七个…...
RabbitMQ 的介绍与使用
一. 简介 1> 什么是MQ 消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message而已。 其主要用途:不同进程Process/线程T…...
【手撕算法】K-Means聚类全解析:从数学推导到图像分割实战
摘要 聚类算法是探索数据内在结构的利器!本文手撕K-Means核心公式,结合Python代码实现与图像分割案例,详解: ✅ 欧氏距离计算 ✅ 簇中心迭代更新 ✅ 肘部法则优化 目录 摘要 目录 一、算法核心思想 二、数学原理详解 2.1 …...
【SQL技术】不同数据库引擎 SQL 优化方案剖析
一、引言 在数据处理和分析的世界里,SQL 是不可或缺的工具。不同的数据库系统,如 MySQL、PostgreSQL(PG)、Doris 和 Hive,在架构和性能特点上存在差异,因此针对它们的 SQL 优化策略也各有不同。这些数据库…...
RabbitMQ系列(二)基本概念之Publisher
在 RabbitMQ 中,Publisher(发布者) 是负责向 RabbitMQ 服务器发送消息的客户端角色,通常被称为“生产者”。以下是其核心功能与工作机制的详细解析: 一、核心定义与作用 消息发送者 Publisher 将消息发送到 RabbitMQ 的…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
rknn toolkit2搭建和推理
安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 ,不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源(最常用) conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...
