一、Android程序的生成步骤
APK是AndroidPackage的缩写,实际上APK文件就是一个zip类型的压缩包,使用zip格式解压缩会发现它由图片、字符串等资源和dex文件组成,dex文件就是dalvik虚拟机的可执行文件。现在安卓开发基本都是用Android Studio了。APK打包的过程分为七个步骤
第一步,打包资源文件生成R.java文件。打包资源使用的工具可以在android SDK中找到,它首先对AndroidManifest.xml的合法性进行检查,然后对res目录下的资源子目录进行处理,然后编译res和asserts目录下的资源并生成resources.arsc文件,最后生成R.java,在之后对res目录下的xml文件进行编译,这一步相当于加密,最后所有资源和resources.arsc文件以及AndroidManifest.xml打包压缩成为resources.ap_文件。
第二步,处理aidl(android接口定义语言)文件,生成相应的java文件。使用的工具是aidl,对于没有用到aidl的安卓工程,这一步可以跳过。aidl也在androidSDK中可以找到
第三步,编译工程源代码,生成相应的class文件,调用javac编译src目录下所有java代码,若果如果使用NDK开发的话,还可能需要使用AndroidNDK编译C/C++代码
第四步,将所有class文件转换为dex文件,使用工具是dx,主要工作是转换格式、压缩常量池、消除冗余信息
第五步,打包生成APK,使用的工具为apkbuilder,它是一个脚本文件,实际上调用的是sdklib.jar中的ApkBuilderMain类。先构建一个apkbuilder类,然后以包含resources.arsc的文件为基础生成apk文件,然后添加各种资源,接着写入依赖库,添加libs目录下的Native库,最后关闭apk文件
第六步,对apk文件签名。一种是调试程序时的签名,使用的JDK中的jarsigner;另一种是打包发布的时候进行签名,使用的是Android源码中的signapk工具。
第七步,对签名后的文件进行对齐处理。使用的是zipalign,将所有资源文件其实便宜为4字节的整数倍,这样通过内存映射访问apk文件时速度更快。
二、安卓程序的安装流程
apk安装分为四种:系统程序开机自动安装、android市场安装、ADB工具安装、手机自带apk安装。
第一种有开机启动时的PackageManagerService服务完成,在启动时自动扫描/system/app路径下的程序并重新安装,这个路径默认是只读的;
第四种是调用安卓系统中的packageinstaller.apk来完成安装。收到应用安装请求,系统启动PackageInstaller,接受Intent传过来的待安装apk信息,启动过程首先会解析程序包信息,解析失败则返回,成功则启动PackageInstallerActivity。PackageInstallerActivity调用的函数有两个比较重要,分别是getPackageInfo()和initiateInstall(),前者解析安装包中各种信息,并构建package对象将解析的信息添加进去;后者检测该程序是否已经安装过,然后根据结果进行安装或者替换更新
三、dex文件格式
dex文件整体结构分为:dex header、string_ids、type_ids、proto_ids、field_ids、method_ids、class_def、data、link_data。在安卓源码dalvik/libdex/Dexfile.h中有介绍
dex header为dex文件的文件头,指定dex文件的属性,记录其他几部分在文件中的偏移,string_id到class_def几部分则为索引结构区,程序真正会用到的数据放在data区,最后link_data为静态链接数据区。
dex header中有几个字段比较重要,magic字段标识一个有效的dex文件,目前的值为“64 65 78 01 30 33 35 00”,转换为字符串为“dex.035”,checksum是校验和,对dex文件进行修改之后要把校验和重新计算然后覆盖这一字段才能成功运行;signature字段用于识别优化之前的dex文件;filesize指示了文件大小,endianTag指定了cpu字节序的大小端。
dalvik虚拟机解析dex文件之后,会将其映射为DexMapList,其结构如下:
struct DexMpList{
u4 size;//u4表示4字节无符号数
DexMapItem list[1];
};
struct DexMapItem {
u2 type;
u2 unused;
u4 size;
u4 offset;
};
type是枚举常量,形式为kDexType*,size指定这种类型的个数,offset是指该类型文件的起始偏移地址
四、odex文件格式
odex全称OptimizedDEX,表示经过优化的dex文件。Android程序apk文件为zip压缩包格式,dalvik虚拟机每次加载它们需要从apk中读取classes.dex文件,耗费大量CPU时间,而odex文件已经包含了加载dex必须的依赖库文件列表,只需要检测并加载需要的依赖库即可,大大缩短了读取dex文件所需时间。
odex生成:(1)使用dexopt-wrapper工具(2)从apk中提取,这种多是Android ROM的系统程序(3)dalvik-cache缓存文件
odex文件结构:它是dex文件的一个超集,由odex文件头、dex文件、依赖库、辅助数据组成