这是关于Android最新版本Kitkat系列文章的第一篇,我把它们写在了+novex Gmbh上面。这个系列将带你从(系统)开发人员的角度深入理解Kitkat的内部机制以及相比之前版本的变化。这里会从新的运行时ART(Android Runtime)开始。
1、引擎检视:什么是ART
Kitkat最令人兴奋、却也最少见诸报端的特性之一就是ART,这个处于试验阶段的最新运行时。Google并没有发布太多有关ART的信息(http://goo.gl/9Jzgdo),尽管事实上它已经出现了。然而,我觉得这个特性可能对未来的发布产生巨大的影响,因为有了ART后Android将不再理会执行过的dalvik字节码,转而使用一种平台特有的、提前编译(AOT,ahead-of-time)二进制码。
Dalvik虚拟机遵循传统Java虚拟机的运行方式:源码编译成平台无关的字节码,随后字节码立即编译成机器码(JIT-Just in time编译)。ART使用了另一种实现方式:它使用AOT范例将代码编译成前期执行的本地代码。但是,这是如何实现的呢?
鉴于在Android市场上基于当前三大不同的体系结构(MIPS,x86,ARM)催生了多种多样的平台,应用程序之间相互可移植性(inter-portability)变得十分重要。他们不得不找到一种方式整合两个世界:互相可移植性和执行本地二进制代码。就目前所知,他们的解决方案在移动领域是独一无二的:将中间字节码装运成可执行代码,然后在目标设备上执行最后的编译步骤——“提前编译”。
对ART进一步的观察显示:他们在最后的编译步骤中使用了LLVM。这种对本地代码的编译处理过程在安装应用时可以流畅地完成。
除此之外,Android小组还面临着一个额外的挑战:兼容业已存在的Dalvik虚拟机/DEX技术。为了处理这个问题,他们引入了一种把dex格式转变成新的oat格式的方法。请继续阅读获取更多的细节:
2、启动的故事:从dex到oat
让我们来探究一下Android是如何在不必重新发布应用的情况下,基于ART执行业已存在的程序。
在接下来的步骤中,我将使用一些新工具,他们伴随新的运行时一起出现:dex2oat和oatdump。这两个工具可以在<aosproot>out/host/<yourplatform>/bin/dex2oat中找到。除此之外,还会用到一些常见的linux工具如objdump、nm、hexdump和hexedit。
从Dalvik运行时转换到ART之后,当系统更新已经安装应用时,启动程序花费了很长一段时间——大约有10分钟。进一步查看ADB输出可以看到正在发生些什么:很显然,dex2oat创建了某种“镜像”。
1 | I /art ( 123): GenerateImage: /system/bin/dex2oat --image= /data/dalvik-cache/system @framework@boot.art@classes.dex--runtime-arg-Xms64m--runtime-arg-Xmx64m--dex- file = /system/framework/core-libart .jar--dex- file = /system/framework/conscrypt .jar--dex- file = /system/framework/okhttp .jar--dex- file = /system/framework/core-junit .jar--dex- file = /system/framework/bouncycastle .jar--dex- file = /system/framework/ext .jar--dex- file = /system/framework/framework .jar--dex- file = /system/framework/framework2 .jar--dex- file = /system/framework/telephony-common .jar--dex- file = /system/framework/voip-common .jar --dex- file = /system/framework/mms-common .jar --dex- file = /system/framework/android .policy.jar --dex- file = /system/framework/services .jar --dex- file = /system/framework/apache-xml .jar --dex- file = /system/framework/webviewchromium .jar --oat- file = /data/dalvik-cache/system @framework@boot.art@classes.oat--base=0x60000000--image-classes-zip= /system/framework/framework .jar--image-classes=preloaded-classes |
system_server启动后在log中显示为“art”的这个进程,通过dex2oat工具创建了一个巨大的“镜像”文件。命令行参数映射包含下面几部分:
在创建镜像期间,所有已包含在内的dex文件会被编译。例如:
1 | W /dex2oat ( 397): Verification of void org.ccil.cowan.tagsoup.HTMLSchema.<init>() took 187.968ms |
看起来很熟悉,对不对?记得dalvik驱动环境中的zygote吧?基本情况是,样版镜像运行了事实上的应用、代码以及那些被频繁使用的类。可以明确的是,xygote没有被取代,它依然存在于ART环境中,你可以用跟dalvik一样的方式来处理它。
在更早的启动过程中,包管理器在每一个已安装的应用中运行dexopt。但除此之外,dex2oat编译器会把每一个已经产生的dex文件编译成oat文件。
1 2 | I /PackageManager ( 559): Running dexopt on: com.android.inputmethod.latin I /dex2oat ( 918): dex2oat: /data/dalvik-cache/system @app@LatinIME.apk@classes.dex |
好吧。现在让我们总结一下目前为止我们所了解到的内容:我们知道ART使用了zygote,就像镜像一样,之后很可能执行了实际的应用程序。同时它也进行了大量的编译,甚至是对框架类的编译。这意味着着从字面上看,我们熟知的Android整个系统都被改变了。我认为这是一个暗示:ART不仅仅是一个“更好的Dalvik”——还意味着范例上的一个改变。
但是现在,我已经开始准备该系列的下一篇。在下一篇中我们将进一步查看这种新的可执行文件格式:OAT文件分析。
联系客服