当前位置: 首页 > news >正文

Android APK组成编译打包流程详解

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


一、APK 的组成

APK 是一个 ZIP 格式的压缩包,包含应用运行所需的所有文件。解压后主要包含以下内容:

  1. classes.dex

    • 由 Java/Kotlin 代码编译后的 Dalvik/ART 字节码文件。

    • 如果方法数超过 65536,会生成多个 classes2.dexclasses3.dex 等(需启用 MultiDex)。

  2. resources.arsc

    • 编译后的二进制资源索引表,包含字符串、布局、颜色等资源的映射关系,用于快速查找资源。

  3. AndroidManifest.xml

    • 应用的配置文件(二进制格式),声明包名、权限、组件(Activity/Service 等)、最低 SDK 版本等。

  4. res/ 目录

    • 存放编译后的资源文件(图片、布局 XML、动画等),原始 XML 会被编译为二进制格式以优化读取效率。

  5. assets/ 目录

    • 存放原始资源文件(如字体、配置文件),通过 AssetManager 直接访问,不参与资源 ID 生成。

  6. lib/ 目录

    • 存放原生库(.so 文件),按 CPU 架构分目录(如 armeabi-v7aarm64-v8ax86)。

  7. META-INF/ 目录

    • 包含应用签名信息(MANIFEST.MFCERT.SFCERT.RSA),用于验证 APK 完整性。

  8. kotlin/ 目录

    • 如果使用 Kotlin,会包含 Kotlin 标准库的相关文件。

  9. 其他文件

    • 如 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.dexresources.arsclib/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时的速度会更快。

工具名称功能介绍在操作系统中的路径
aaptAndroid资源打包工具${ANDROID_SDK_HOME}/build-tools/30.0.0/aapt
aidlAndroid接口描述语言转化为.java文件的工具${ANDROID_SDK_HOME}/build-tools/30.0.0/aidl
javacjava 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(传输控制协议)中的长连接和短连接是两种不同的连接管理方式,各有优缺点: 短连接 短连接是指客户端与服务器完成一次数据交换后就断开连接。下次需要通信时,再重新建立连接。 特点&#xff1…...

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的配置文件,添加自己的私库地址&#xff0c…...

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>关于主题创建 理论…...

技术问题汇总:前端怎么往后端传一个数组?

场景 现在一个专门负责复习算法的服务&#xff0c;筛选出了用户今天需要复习的笔记的ids&#xff0c;现在要调用笔记服务根据ids查询的接口。 请问复习服务怎么将ids发到笔记服务&#xff0c;笔记服务怎么接收。 思路 发的时候肯定是用字符串&#xff0c;接收的时候&#xf…...

【03】STM32F407 HAL 库框架设计学习

【03】STM32F407 HAL 库框架设计学习 摘要 本文旨在为初学者提供一个关于STM32F407微控制器HAL&#xff08;Hardware Abstraction Layer&#xff09;库框架设计的详细学习教程。通过本文&#xff0c;读者将从零开始&#xff0c;逐步掌握STM32F407的基本知识、HAL库的配置步骤…...

智能图像处理平台:图像处理配置类

这里我们先修改一下依赖&#xff0c;不用JavaCV&#xff0c;用openCV。 导入依赖&#xff1a; <!-- JavaCV 依赖&#xff0c;用于图像和视频处理 --> <!-- <dependency>--> <!-- <groupId>org.bytedeco</groupId>--> &l…...

【图文详解】什么是微服务?什么是SpringCloud?

目录 一.认识微服务架构 ??微服务带来的挑战 二.微服务解决方案SpringCloud ??SpringCloud的版本 ??SpringCloud和SpringBoot的关系 ??SpringCloud实现方案 Spring Cloud Netfix Spring Cloud Alibaba ??Spring Cloud 实现对比 在入门Spring Cloud 之前&…...

基于ssm的校园跑腿管理系统+vue

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统共有管理员、用户两个角色 管理员主要的功能用户信息管理、任务信息管理、任务类型管理、接单信息管理、公告信息管理、投诉信息管理、公告类型管…...

5个GitHub热点开源项目!!

1.自托管 Moonlight 游戏串流服务&#xff1a;Sunshine 主语言&#xff1a;C&#xff0c;Star&#xff1a;14.4k&#xff0c;周增长&#xff1a;500 这是一个自托管的 Moonlight 游戏串流服务器端项目&#xff0c;支持所有 Moonlight 客户端。用户可以在自己电脑上搭建一个游戏…...

docker通用技术介绍

docker通用技术介绍 1.docker介绍 1.1 基本概念 docker是一个开源的容器化平台&#xff0c;用于快速构建、打包、部署和运行应用程序。它通过容器化技术将应用及其依赖环境&#xff08;如代码、库、系统工具等&#xff09;打包成一个标准化、轻量级的独立单元&#xff0c;实…...

#渗透测试#批量漏洞挖掘#某图创图书馆集群管理系统updOpuserPw SQL注入(CVE-2021-44321)

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

智能合约安全 | 合约无效化攻击

目录&#xff1a; 智能合约安全 合约无效化攻击 合约自毁函数 selfdestruct 攻击实现 漏洞防御 总结 智能合约安全 合约无效化攻击 合约无效化攻击类同于web安全中的逻辑漏洞中的一种 我们这里拿一个典型的例子来讲解 有这样一份智能合约, 每个人可以向其中发送1 eth 第七个…...

RabbitMQ 的介绍与使用

一. 简介 1> 什么是MQ 消息队列&#xff08;Message Queue&#xff0c;简称MQ&#xff09;&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO先入先出&#xff0c;只不过队列中存放的内容是message而已。 其主要用途&#xff1a;不同进程Process/线程T…...

【手撕算法】K-Means聚类全解析:从数学推导到图像分割实战

摘要 聚类算法是探索数据内在结构的利器&#xff01;本文手撕K-Means核心公式&#xff0c;结合Python代码实现与图像分割案例&#xff0c;详解&#xff1a; ✅ 欧氏距离计算 ✅ 簇中心迭代更新 ✅ 肘部法则优化 目录 摘要 目录 一、算法核心思想 二、数学原理详解 2.1 …...

【SQL技术】不同数据库引擎 SQL 优化方案剖析

一、引言 在数据处理和分析的世界里&#xff0c;SQL 是不可或缺的工具。不同的数据库系统&#xff0c;如 MySQL、PostgreSQL&#xff08;PG&#xff09;、Doris 和 Hive&#xff0c;在架构和性能特点上存在差异&#xff0c;因此针对它们的 SQL 优化策略也各有不同。这些数据库…...

RabbitMQ系列(二)基本概念之Publisher

在 RabbitMQ 中&#xff0c;Publisher&#xff08;发布者&#xff09; 是负责向 RabbitMQ 服务器发送消息的客户端角色&#xff0c;通常被称为“生产者”。以下是其核心功能与工作机制的详细解析&#xff1a; 一、核心定义与作用 消息发送者 Publisher 将消息发送到 RabbitMQ 的…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...