编译指令
- mmm:编译指定目录下的模块,不编译它所依赖的其它模块。
- mma:编译当前目录下的模块及其依赖项。
- mm:编译当前目录下的模块,不编译依赖模块。
- mmma:编译指定路径下所有模块,并且包含依赖。
注意一般第一次使用 mm 进行编译时,可能会出现某些文件资源找不到,可以先使用 mma 编译相关依赖项,之后可以直接使用 mm 命令进行编译
编译步骤
- 初始化
这里以 Launcher 模块为例进行说明
在AOSP根目录执行:
//注意每次打开新的终端窗口都需要执行如下命令
source build/envsetup.sh
lunch 47
- 进入Settings的目录:
cd /AOSP/packages/apps/Launcher3
- mm编译当前目录下的模块,不编译依赖模块
mm
编译成功则如下图所示
安装
当修改了相关代码之后,我们向查看修改的效果那怎么办呢?有两种方式:
- 可以在编译完成后,借助 adb install -r apk路径直接将生成的 apk 文件安装到设备上,如果不是 APK,直接 push 对应的文件
- 可以编译好完成后,再使用make snod,重新生成 system.img,烧录进设备
这里因为Launcher模块编译之后会生成APK安装包,所以我们直接进行安装即可:
- 进入 APK目录
cd AOSP/out/target/product/sailfish/system/priv-app/Launcher3
- adb安装
adb install -r Launcher3.apk
系统优化与dex/odex/vdex/oat/art
在上述编译过程中在输出的文件中不仅仅包括apk、同时还有odex和vdex文件,那么这些文件都是干什么用的?接下来就这一问题展开探讨。众所周知,Android为每一个应用程序都创建了一个虚拟机去运行,这样每个应用程序都是独立的互不干扰的运行,其中一个出现崩溃,并不会影响应用程序的运行,因此我们先从Android虚拟机开始讨论。
Android虚拟机
Dalvik 与 ART 的区别
Dalvik:
JIT(Just-in-time)实时编译,运行的时候将字节码翻译成机器码,所运行的目标文件(dex)与硬件平台无关,App运行效率较低
ART:
AOT(Ahead-Of-Time)预先编译,运行前将字节码翻译成机器码,所运行的目标文件(oat)与硬件平台相关。App运行效率高,但会占用空间,同时Apk安装所需要时间增加。
vdex
android 8.0 新增的格式包,dex代码直接转化的可执行二进制码文件,在Android 8.0 之后 odex 是从vdex 这个文件中 提取了部分模块生成的一个新的 可执行二进制码 文件 ,odex 从vdex 中提取后,vdex 的大小就减少了;
- 第一次开机就会生成在/system/app/<packagename>/oat/ 下
- 在系统运行过程中,虚拟机将其 从 “/system/app” 下 copy 到 “/data/davilk-cache/” 下
- odex + vdex = apk 的全部源码 (vdex 并不是独立于odex 的文件 odex + vdex 才代表一个apk )
odex
Dalvik 时代: APK 运行的时候,会把 APK 中的 classes.dex 解压出来并通过 dexopt 优化 .odex 文件,缓存在 /data/dalvick-cache 目录下,提高后续的执行效率(Android 5.0以后更改为ART虚拟机,但手机厂商认为ART技术还不成熟,所以部分还沿用Dalvik)。
ART 时代:APK 安装的时候,会把 APK 中的 classes.dex 解压后,通过 dex2oat 工具转化为 .odex 文件 (ELF模式,与Dalvik生成的完全不同),存储在 apk 所在目录的 oat 目录下;
为什么源码环境下编译就产生了odex文件?
我们知道 ROM 是由apk、jar、bin、so等组成,那么虚拟机在进行转换翻译的时机是什么时候呢?显然 apk 是在安装的时候,jar包 是在加载的时候,而 ROM 是在手机开机的时候被加载和安装,针对上述特性,总结这样做的优缺点:
优点:
- 降低系统更新后启动的时间
未 odex 的 Rom, 首次开机的过程中会执行 odex 操作,如果将这个过程放在编译时刻,就减少了开机时间 - 减少在设备上的空间浪费
apk文件中的dex如果不删除,同一个应用就会存在两个dex文件:apk中和data/dalvik-cache目录下 - 防止第三方用户反编译系统的软件(odex文件是跟随系统环境变化的,改变环境会无法运行;而apk文件中又不包含dex文件,无法独立运行)
缺点:
- 增加开发时编译的时间
- 不能直接执行 APK 的 install 操作,需要将 APK 和 odex 都同步到设备上
关于APK中是否存在dex的观点暂做保留,笔者编译Android9.0中的Launcher模块,apk中存在dex
art
odex 进行优化生成的可执行二进制码文件,主要是apk 启动的常用函数相关地址的记录,方便寻址相关; 通常会在data/dalvik-cache/保存常用的jar包的相关地址记录
1.odex 文件在运行时,虚拟机会计算函数调用频率,进行函数地址的修改;
2.最后在/data/davilk-cache/ 由虚拟机生成;
3.生成art 文件后,/system/app 下的odex 和 vdex 会无效,即使你删除,apk也会正常运行
oat
ART虚拟机使用的是oat文件,oat文件是一种Android私有ELF文件格式,它不仅包含有从DEX文件翻译而来的本地机器指令,还包含有原来的DEX文件内容。APK在安装的过程中,会通过dex2oat工具生成一个OAT文件。对于apk来说,oat文件实际上就是对odex文件的包装,即oat=odex,而对于一些framework中的一些jar包,会生成相应的oat尾缀的文件,如system@framework@boot-telephony-common.oat
参考
[ 1 ]:https://www.jianshu.com/p/f48eac038384
[ 2 ]:http://wuxiaolong.me/2018/07/25/AOSP2/