Welcome to Ray's Blog

Stay Hungry Stay Foolish - Steve Jobs

0%

Android 打包流程笔记


流程概述:

  1. 打包资源(/res/)文件,生成 R.java 文件;
  2. 处理 aidl 文件,生成相应的 java 文件;
  3. 编译工程源代码,生成相应 class 文件;
  4. 转换所有的 class 文件,生成 classes.dex 文件;
  5. 打包生成 apk;
  1. 对 apk 文件进行签名;
  2. 对签名后的 apk 文件进行对齐处理。

android 打包使用工具:

名称 功能介绍 在操作系统中的路径 源码路径
aapt(Android Asset Package Tool) Android 资源打包工具 ${ANDROID_SDK_HOME}/build-tools/ANDROID_VERSION/aapt frameworkds\base\tools\aap
aidl(Android Interface definition language) Android 接口描述语言,将 aidl 转化为.java 文件的工具 ${ANDROID_SDK_HOME}/build-tools/ANDROID_VERSION/aidl frameworks\base\tools\aild
javac Java Compiler ${JDK_HOME}/javac 或/usr/bin/javac
dex 转化.class 文件为 Davik VM 能识别的.dex 文件 &{ANDROID_SDK_HOME}/build-tools/ANDROID_VERSION/dx
apkBuilder 生成 apk 包 &{ANDROID_SDK_HOME}/tools/sdk\sdkmanager\libs\sdklib\src\com\android\sdklib\build${ANDROID_SDK_HOME}/tools/apkbuilderApkBuilderMain.java sdk\sdkmanager\libs\sdklib\src\com\android\sdklib\build\ApkBuilderMain.java
jarsigner .jar 文件的签名工具 ${JDK_HOME}/jarsigner 或/usr/bin/jarsigner
zipalign 字节码对齐工具 ${ANDROID_SDK_HOME}/tools/zipalign

打包步骤详解

第一步:打包资源文件,生成 R.java 文件

【输入】Resource 文件(就是工程中 res 中的文件)、Assets 文件(相当于另外一种资源,这种资源 Android 系统并不像对 res 中的文件那样优化它)、AndroidManifest.xml(包名就是从这里读取的,因为生成 R.java 文件需要包名)、Android 基础类库(Android.jar 文件)
【工具】aapt 工具
【输出】打包好的资源(bin 目录中的 resources.ap文件)、R.java 文件(gen 目录中),打包资源的工具 aapt,大部分文本格式的 XML 资源文件会被编译成二进制格式的 XML 资源文件,除了 assets 和 res/raw 资源被原装不动的打包进 APK 之外,其他的资源都会被编译或者处理。生成过程主要是条用了 aapt 源码目录下的 Resource.cpp 文件中的 buildResource()函数,该函数首先检查 AndroidManifest.xml 的合法性,然后对 res 目录下的资源子目录进行处理,处理的函数为 makeFileResource(),处理的内容包括资源文件名的合法性检查,向资源表 table 添加条目等,处理完后调用 compileResouceFile()函数编译 res 与 assets 目录下的资源并生成 resources.arsc 文件,complieResourceFile()函数位于 aapt 源码目录的 ResourceTable.cpp 文件中,该函数最后会调用 parseAndAddEntry()函数生成 R.java 文件,文成资源编译后,接下来调用 compileXmlfile()函数对 res 目录的子目录下的 xml 文件进行编译,这样处理过的 xml 文件就简单的被“加密”了,最后将所有的资源与编译生成的 resources.arsc 文件以及“加密“过的 AndroidManifest.xml 文件打包压缩成 resources.ap文件(使用 Ant 工具命令行编译则会生成与 build.xml 中”project name”指定的属性同名的 ap_文件)。
关于这一步更详细的流程可阅读罗升阳的 blog

第二步:处理 aidl 文件,生成相应的 java 文件

【输入】源码文件、aidl 文件、framework.aidl 文件
【工具】aidl 工具
【输出】对应的.java 文件
对于没有使用到 aidl 的 android 工具,这一步可以跳过。aidl 工具解析接口定义文件并生成相应的 java 代码供程序调用。

第三步:编译工程源代码,生成相应的 class 文件

【输入】源码文件(包 R.java 和 Aidl 生成的.java 文件)、库文件(.jar 文件)
【工具】javac 工具
【输出】.class 文件
这一步调用了 javac 编译工程 src 目录下所有的 java 源文件,生成的 class 文件位于工具的 bin\classes 目录下,上图嘉定编译工程源代码时程序是基于 android sdk 开发的,实际开发过程中,也有可能会使用 android ndk 来编译 native 代码。因此,如果可能的话,这一步还需要使用 android NDK 编译 C/C++代码,当然,编译 C/C++代码步骤也可以提前到第一步或者第二步完成。

第四步:转换所有的 class 文件,生成 classes.dex 文件

【输入】 .class 文件(包括 aidl 生成.class 文件,R 生成的.class 文件,源文件生成的.class 文件),库文件(.jar 文件)
【工具】dex 工具
【输出】.dex 文件
android dalvik 虚拟机的可执行文件为 dex 格式,程序运行所需要的 classes.dex 文件就是在这一步生成的,使用的工具为 dex,dex 工具的主要工作就是件 java 字节码转换成为 dalvik 字节码,压缩常量池、消除冗余信息等。

第五步:打包生成 apk

【输入】打包后的资源文件,打包后类文件(.dex 文件)、libs 文件(包括.so 文件,当然很多工程都没有这样的文件,如果你不使用 c/c++开发的话)
【工具】apkbuilder 工具
【输出】未签名的.apk 文件
打包工具为 apkbuilder,apkbuilder 为一个脚本文件,实际调用的是 android-sdk\tools\lib\sdklib.jar 文件中的 com.android.sdklib.build.ApkBuilderMain 类。他的代码实际位于 android 系统源码的 sdk\sdkmanager\libs\sdklib\src\com\android\sdklib\build\ApkBuilderMain.java 文件,代码构建了一个 ApkBuilder 类,然后以包含 resources.arsc 的文件为基础生成 apk 文件,这个文件一般以 ap_结尾,接着调用 addSourceFolder()函数添加工程 libs 目录下的 Native 库(通过 androidNDK 编译生成的 so 或者 bin 文件),还调用 sealApk()关闭 apk 文件。

第六步:对 apk 文件进行签名

【输入】未签名的.apk 文件
【工具】jarsigner
【输出】签名的.apk 文件
android 的引用程序需要签名才能在 android 设备上安装,签名 apk 文件有俩种情况:一种是在调试程序时进行签名,使用 eclipse 开发 android 程序时,在编译调试程序时会自己使用一个 debug.keystore 对 apk 进行签名;另一种是打包发布时对程序进行签名,这种情况下需要提供一个符合 android 开发文件中要求的签名文件。签名的方法也分为俩种:一种是使用 jak 中提供的 jarsigner 工具签名;另一种是使用 android 源码中提供的 signapk 工具,他的代码位于 android 系统源码 build\tools\signapk 目录下。

第七步:对签名后的 apk 文件进行对齐处理

【输入】签名后的.apk 文件
【工具】zipalign 工具
【输出】对齐后的.apk 文件
这一步需要使用的工具是 zipalign 工具,它位于 android-sdk\tools 目录下,源码位于 android 系统源码的 build\tools\zipalign 目录,它的主要工作是将 apk 包进行对齐处理,是 apk 包中的所有资源文件距离文件起始偏移 4byte 整数倍,这样通过内存映射访问 apk 文件时速度会更快,验证 apk 文件是否对齐过的工作右 zipalign.cpp 文件的 verify()函数完成,处理对齐的工作则由 process()函数完成。

引用资源请点我查看