APK是Android Package的缩写,即Android安装包(apk)。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。APK文件基于 zip 文件格式,它与 jar 文件的构造方式相似。
1. APK包中有些什么
文件名称 | 文件类型 | 文件作用 |
classes.dex | 文件 | java源文件经过编译和转换后生成的二进制的字节码文件 |
resource.arsc | 文件 | 经过 aapt 编译后的二进制的资源文件 |
AndroidManifest.xml | 文件 | 经过 aapt 编译后的二进制的 xml 文件 |
res | 文件夹 | 除图片和 res/raw 文件夹下的文件外,其余的 xml 文件都被 aapt 编译成二进制的 xml 文件 |
assets | 文件夹(可选) | 存放不进行编译的原生文件,可以是一些图片,或者是html、js、css文件 |
lib | 文件夹(可选) | 存放应用程序依赖的 native 库文件,一般是用 c/c++ 编写,如 so 文件 |
META-INF | 文件夹 | 存放签名信息以及每一个文件的哈希值(BASE64) |
2. 打包用到的工具
工具名称 | 功能介绍 | 在操作系统中的路径 |
aapt | Android资源打包工具 | ${ANDROID_SDK_HOME}/platform-tools/appt |
aidl | Android接口描述语言转化为.java文件的工具 | ${ANDROID_SDK_HOME}/platform-tools/aidl |
javac | Java Compiler | ${JDK_HOME}/javac 或 /usr/bin/javac |
dex | 转化.class文件为Davik VM能识别的.dex文件 | ${ANDROID_SDK_HOME}/platform-tools/dx |
apkbuilder | 生成apk包 | ${ANDROID_SDK_HOME}/tools/opkbuilder |
jarsigner | .jar文件的签名工具 | ${JDK_HOME}/jarsigner 或 /usr/bin/jarsigner |
zipalign | 字节码对齐工具 | ${ANDROID_SDK_HOME}/tools/zipalign |
3. 打包的具体过程
上图显示的是APK打包的流程图。对于每一步具体的流程如下所示:
3.1 打包资源文件,生成相应的 R.java 文件
- 工具:aapt
- 输入:res 文件夹,assets 文件夹,AndroidManifest.xml 文件
- 输出:R.java,二进制的 resource.arsc ,res 文件夹(包括二进制的 xml 文件以及 没有改变的图片和 res/raw 下的文件),没有改变的 assets 文件夹,二进制的 AndroidManifest.xml 文件
1 . R.java
R.java
中有拥有大量的静态内部类,每当有这种资源添加时,就在R.java文件中添加一条静态内部类里的静态常量类成员,且所有成员都是int类型。
2 . resources.arsc
resources.arsc
记录了所有的应用程序资源目录的信息,包括每一个资源名称、类型、值、ID以及所配置的维度信息。其作用类似一个索引表,能够快速指引并找到系统资源。
3.2 处理 AIDL 文件,生成相应的 java 文件
- 工具:aidl(Android Interface Denifition Language)
- 输入:aidl文件
- 输出:相应的 java 接口文件
3.3 编译所有的 java 文件,生成 class 文件
通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件。
- 工具:javac(java 编译器)
- 输入:R.java,java接口文件,java源文件
- 输出:class文件
3.4 把class文件转换成dex文件
通过dex命令,将.class文件和第三方库中的.class文件处理生成classes.dex。
- 工具:dx.bat
- 输入:class文件,第三方库文件.jar(jar包中大都是class文件)
- 输出:classes.dex文件
3.5 打包生成apk文件
将classes.dex、resources.arsc、res文件夹(res/raw资源被原装不动地打包进APK之外,其它的资源都会被编译或者处理)、Other Resources(assets文件夹)、AndroidManifest.xml打包成apk文件。
- 工具:apkbuilder
- 输入:resource.arsc文件,AndroidManifest.xml文件,res文件夹,assets文件夹,classes.dex文件
- 输出:apk文件
res/raw和assets的相同点与不同点:
相同点 | 不同点 |
两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。 | 1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。2.res/raw不可以有目录结构,而assets则可以有目录结构。 |
3.6 对apk文件进行签名
对apk进行签名,可以进行Debug和Release 签名。
- 工具:apksigner
- 输入:未签名的apk文件
- 输出:签名的apk文件
3.7 对签名后的apk文件进行对齐处理
工具:zipalign
输入:签名的apk文件
输出:最终的apk文件
注:如果是release版本,需要对apk文件进行对齐处理。对齐处理使得apk包中的所有资源文件距离文件起始偏移为4字节整数倍,这样通过内存映射访问apk文件时的速度更快,同时减少运行时内存的使用。
参考
- Android开发 —— apk打包流程
- Android 打包过程