Android ART Runtime (2) – dex2oat

篇文章中我们介绍了 Android 4.4 新开发的运行时 ART 项目,其中的一个重要模快是 dex2oat,简单讲就是使用 LLVM 把 dex 文件编译成 oat 文件(Optimized ART?)。下面我们详细研究一下 dex2oat 的功能,以及他是如何被调用的。

一、dex2oat 简介

dex2oat 顾名思义 dex file to oat file,就是在新旧两种运行时文件的转换。他是一个可执行 ELF 文件,adb 连接手机以后也可以直接调用。dex2oat 的源码只有一个文件 /art/dex2oat/dex2oat.cc。dex2oat 有很多参数,并且实用方法打印到 logcat里面,看起来非常不便,我们直接看源码 Usage()。我挑了几个比较重要的参数看了一下,先介绍一下,调用过程中可能会用到。

dex2oat 用法

  • --dex-file=: specifies a .dex file to compile.: 需要转换的 dex 文件,也可以是 apk, jar,dex2oat 会找到里面的 classes.dex 进行转换。
  • --oat-file=: specifies the oat output destination via a filename.: 指定输出 oat 的文件名。
  • --boot-image=: provide the image file for the boot class path.: 系统运行时工具类在 ART 下编译后的文件,他的例子是指向/system/framework/boot.art。但其实 boot.art 不在这个目录下,而是在/data/dalvik-cache/system@[email protected]。后面还会详细介绍这个 boot 文件。
  • --compiler-backend=(Quick|QuickGBC|Portable): select compiler backend": dex2oat 好像只处理了 Quick 和 Portable 两种编译 backend,暂时还不理解有什么区别,待以后继续研究。

其他参数大多都能从他的描述中知道用途,等以后用到的时候再详细看。

oat 文件在哪里?
我们知道选择 ART 作为运行时后,需要重启手机。然后系统会使用 dex2oat 把所有 App 编译成 oat 文件。那么 oat 都存在哪里?我怎么找不到?通过查看代码和开机的 log,发现 oat 文件原来在 /data/dalvik-cache/*@classes.dex。竟然和 odex 文件名字一样!检验一下文件格式:

果然是 ELF 文件。

二、调用过程分析

PackageManagerService 是负责 apk 包管理的服务,包括安装,检查,删除,更新等等所有与 apk 相关的服务。我在源码中研究了一下 dex2oat 详细的调用过程,在下面介绍过程的时候我打算从 PackageManagerService 入手,经过一系列的调用过程才真正执行 dex2oat。

PackageManagerService (PMS)
我们知道 PMS 服务启动之后会监控某些目录(/data/data/ 等)。如果目录多了某个文件,PMS 会调用一些方法对文件进行处理。扫描监控目录的方法是:scanDirLI(),在 PackageManagerService 的构造方法中调用,详见代码 /frameworks/base/services/java/com/android/server/pm/PackageManagerService.java

从源码中可以看到,有四个地方调用 scanDirLI()。再调用之前有一个 AppDirObserver 类引起了我的注意,看一下是怎么对目录进行监控的。依然是在 PackageManagerService 中找到了 AppDirObserver 继承于 FileObserver。FileObserver 有一个 native 方法 startWatching 找到了他的实现 /frameworks/base/core/java/android/os/FileObserver.java

man 一下 inotify_add_watch:

原来 inotify_add_watch() 是监控目录的。

PackageManagerService.scanDirLI()

回到正题,我们从构造方法中找到了 scanDirLI(),现在来看一下 scanDirLI() 都做了什么:

你可能感兴趣的:(android)