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时的速度会更快。
工具名称功能先容在操纵体系中的路径aaptAndroid资源打包工具${ANDROID_SDK_HOME}/build-tools/30.0.0/aaptaidlAndroid接口描述语言转化为.java文件的工具${ANDROID_SDK_HOME}/build-tools/30.0.0/aidljavacjava Compiler java代码转class文件${JDK_HOME}/javac或/usr/bin/javacdex转化.class文件为Davik VM能识别的.dex文件${ANDROID_SDK_HOME}/build-tools/30.0.0/dxapkbuilder天生apk包???没有找到jarsigner.jar文件的签名工具${JDK_HOME}/jarsigner或/usr/bin/jarsignerzipalign字节码对齐工具${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 打包流程
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |