Android应用篇 - 打包流程分析

平时都是直接用 gradle 打包,今天来分析一下 Android 的打包流程。

目录:

  1. 流程图
  2. 具体步骤分析

1. 流程图

2. 具体步骤分析

扫描二维码关注公众号,回复: 9637119 查看本文章

打包的工具链:

aapt -> aidl -> javac -> dx -> apkbuilder -> jarsigner -> zipalign

现在来一步步分析。

  • 2.1 aapt

aapt 为 Android 资源打包工具,目录为 ${ANDROID_SDK_HOME}/platform-tools/appt。

aapt 工具编译 res 资源文件,把大部分 xml 文件编译成二进制文件 (图片文件除外),同时生成 R.Java 文件和 resources.arsc 文件,里面保存了资源的 ID 和在 APK 中的路径。

需要进入应用程序目录,新建一个 gen 目录,没有 gen 目录,aapt 命令将会出现找不到文件的错误。

(1) Android 是如何通过 R 文件引用到真正的资源文件?

aapt 工具对于每个资源文件生成了唯一的 ID,这些 ID 保存在 R.java 文件中。比如:

public final class R {
    public static final class anim {
        public static final int abc_fade_in=0x7f050000;
        public static final int abc_fade_out=0x7f050001;   
    }
    
    public static final class array {
        public static final int smssdk_country_group_a=0x7f090000;
        public static final int smssdk_country_group_b=0x7f090001;
    }
    
    public static final class bool {
        public static final int abc_action_bar_embed_tabs=0x7f0c0000;
        public static final int abc_allow_stacked_button_bar=0x7f0c0001;
        public static final int abc_config_actionMenuItemAllCaps=0x7f0c0003;
        public static final int abc_config_closeDialogWhenTouchOutside=0x7f0c0004;
        public static final int abc_config_showMenuShortcutsWhenKeyboardPresent=0x7f0c0005;
        public static final int useHardwareAcceleration=0x7f0c0002;
    }
    public static final class color {
        public static final int abc_background_cache_hint_selector_material_dark=0x7f0e00cc;
        public static final int abc_background_cache_hint_selector_material_light=0x7f0e00cd;
        public static final int abc_btn_colored_borderless_text_material=0x7f0e00ce;
        public static final int abc_color_highlight_material=0x7f0e00cf;
        public static final int abc_hint_foreground_material_dark=0x7f0e00d0;
        public static final int abc_hint_foreground_material_light=0x7f0e00d1;
    }
    // ...
}

资源 ID 是一个 4 字节的无符号整数,在 R.java 文件中用 16 进制表示。其中,最高的 1 字节表示 Package ID,次高 1 个字节表示 Type ID,最低 2 字节表示 Entry ID。只有一个 ID 如何能引用到实际资源呢?实际上 aapt 工具还生成了一个文件resources.arsc,相当于一个资源索引表,或者你理解成一个 map 也行,map 的 key 是资源 ID,value 是资源在 apk 文件中的路径。resources.arsc 里面还有其他信息,这个就不多说了。通过 R.java 文件和 resources.arsc 配合,就能引用到实际的资源文件。

(2) 为什么要把xml文件编译成二进制文件?

xml 里面都是各种字符,不利于快速遍历。编译成二进制文件,用数字替换各种符号,一方面能快速访问,另一方面也能减少大小。

  • 2.2 aidl

aidl 为 Android 接口描述语言转化为 .java 文件的工具,目录为 ${ANDROID_SDK_HOME}/platform-tools/aidl。

如果项目中有使用 aidl,那么就会把 .aidl 文件编译成 .java 文件。

  • 2.3 javac

Java Compiler,目录为 ${JDK_HOME}/javac 或者 /usr/bin/javac。

将所有 .java 文件 (包括 R 文件和 aidl 生成的 .java 文件),通过 javac 工具生成 class 文件。

  • 2.4 dx

dx 为 转化 .class 文件为 Davik/ART VM 能识别的 .dex 文件的工具,目录为 ${ANDROID_SDK_HOME}/platform-tools/dx。

将生成的 .class 文件和第三方库的 .class 文件通过 dx 工具生成 classes.dex 文件 (如果有分包,那么可能有多个)。

  • 2.5 apkbuilder

apkbuilder 为生成 apk 包的工具,目录为 ${ANDROID_SDK_HOME}/tools/opkbuilder。

将 resources.arsc、dex 文件和第三方的非 java 资源包 (.so),通过 apkbuilder 工具生成未签名的 apk 包。

  • 2.6 jarsigner

jarsigner 为 .jar 文件的签名工具,目录为 ${JDK_HOME}/jarsigner 或 /usr/bin/jarsigner。

使用 jarsigner 对 apk 进行签名,如果是 debug 模式用默认签名,release 模式用开发者的签名。

  • 2.7 zipalign

zipalign 为字节码对齐工具,目录为 ${ANDROID_SDK_HOME}/tools/zipalign。

通过 zipalign 工具对 apk 中的未压缩资源 (图片、视频) 进行 "对齐操作",让资源按 4 字节的边界进行对齐,使得资源访问速度更快。

发布了126 篇原创文章 · 获赞 215 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/u014294681/article/details/88690666
今日推荐