目录

APK 打包

DakingTech 原创不易,转载请注明出处

APK 打包工具

名称 功能 所在路径
aapt 资源打包工具,全称为 Android Asset Packing Tool {android_sdk}/build-tools/{android api}/aapt
aapt2 第二代资源打包工具,代替 aapt {android_sdk}/build-tools/{android api 24+}/aapt2
aidl 将 .aidl 文件转化成 .java 文件 {android_sdk}/build-tools/{android api}/aidl
kotlinc 将 .kt 文件编译成 .class 文件 {android_studio}/plugins/Kotlin/kotlinc
javac 把 .java 文件编译成 .class 文件 {jdk}/bin/javac
dx 将 .class 文件转化成 .dex 文件 {android_sdk}/build-tools/{android api}/dx
d8 将 .class 文件转化成 .dex 文件,代替 dx {android_sdk}/build-tools/{android api 28+}/d8
zipalign 字节码对齐 {android_sdk}/build-tools/{android api}/zipalign
jarsigner 对 apk 进行签名 {jdk}/bin/jarsigner
apksigner 对 apk 进行签名,代替 jarsigner {android_sdk}/build-tools/{android api 24+}/apksigner

APK 打包过程

1. 编译资源文件

编译资源文件:

  • 工具:aapt2
  • 输入:res 目录下的各 xml 资源文件
  • 输出:各 xml 资源文件的二进制格式、R.java 和 resources.arsc

R.java 定义了各个资源的 ID 常量。

1
2
3
4
5
6
7
8
public final class R {
    public static final class anim {
        public static final int abc_fade_in=0x7f010000;
        public static final int abc_fade_out=0x7f010001;
        ...
    }
    ...
}

资源 ID 是一个4字节的无符号整数,用16进制表示。其中,最高的1字节表示 Package ID,如7f,次高的1字节表示 Type ID,如01,最低的2字节表示 Entry ID。

resources.arsc 相当于一个资源索引表,可以理解为一个 map,其中 key 是 R.java 中的资源 ID,而 value 就是其对应的资源所在路径。于是,结合 R.java 和 resources.arsc 就能找到资源。

/images/2021-05-07-16-28-39.png

res/raw 目录和 asserts 目录下的资源文件不会被编译,它们之后会被原封不动地打包进 apk 中。

2. 处理 AIDL

处理 AIDL:

  • 工具:aidl
  • 输入:.aidl 文件
  • 输出:.java 文件

3. 编译源代码

编译 Java 源代码:

  • 工具:javac
  • 输入:.java 文件(包括 R.java 和第2步处理 AIDL 生成的 .java 文件)
  • 输出:.class 文件

编译 Kotlin 源代码:

  • 工具:kotlinc
  • 输入:.kt 文件
  • 输出:.class 文件

4. 生成 dex

生成 dex:

  • 工具:d8
  • 输入:第3步生成的 .class 文件、第三方库的 .class 文件
  • 输出:classes.dex 文件

如果是 multidex,则可能生成多个 dex 文件,比如 classes.dex、classes2.dex、classes3.dex...

5. 生成 apk

生成 apk:

  • 工具:aapt2
  • 输入:res 目录中各资源文件(各编译后的 xml 资源文件、图片文件、res/raw 等)、classes.dex 文件(可能多个)、resource.arsc、assets 目录中各文件、AndroidManifest.xml 和各 so 文件等
  • 输出:apk 文件

注意,此时的 apk 是未对齐、未签名的。

6. apk 对齐

apk 对齐:

  • 工具:zipalign
  • 输入:未对齐的 apk 文件
  • 输出:已对齐的 apk 文件

对 apk 中的资源文件进行对齐操作,使其起始偏移为4字节的整数倍,这样通过内存映射访问资源时的速度会更快。

7. apk 签名

apk 签名:

  • 工具:apksigner
  • 输入:未签名的 apk 文件
  • 输出:已签名的 apk 文件

目前 Android 有三种签名:V1、V2(Android 7+)、V3(Android 9+),详情查看APK 签名

APK 文件结构

文件 描述
lib 目录 各 abi 子目录/so 文件
res 目录 资源文件
assets 目录 资源文件
META-INF 目录 APK 的摘要和签名信息
resources.arsc 资源索引文件
AndroidManifest.xml Android 清单文件
classes(n).dex Dex 是 DalvikVM executes 的缩写,即 Android Dalvik 执行文件

参考资料

移动端架构师-慕课网

Android 工程师进阶 34 讲-拉勾教育