1.2.3 准备模拟器和自制系统镜像
阅读源码是学习虚拟机的主要方法。但在某些关键地方,有时候很难确定代码逻辑的走向,这时就需要在源码中加一些日志来辅助我们观察虚拟机的行为。在此,笔者推荐使用模拟器和自制系统镜像来帮助我们达到这个目标。
提示 自制系统镜像是由上文下载的Android源码文件编译而来。我们可以随心所欲地通过修改源码文件来定制Android系统。当然,这个由我们自己编译而来的系统只能跑在模拟器中。即便如此,这对我们学习ART虚拟机来说也是莫大的帮助。
1.2.3.1 准备好模拟器
读者需首先安装Android Studio。然后随便打开一个Android应用工程。单击菜单栏右边的avd manager图标,启动AVD界面,如图1-5所示。
图1-5 AVD界面
图1-5中,笔者创建了两个虚拟设备,一个是运行Android 7.0系统的innost-7.0设备,一个是运行Android 9.0系统的innost-9.0设备。
单击图1-6中左下角的“Create Virtual Device”,出现图1-6所示的设备硬件配置界面。
图1-6 设备硬件配置界面
读者可自定义硬件配置或者从谷歌相关手机产品中选一个手机型号。比如Pixel XL。然后单击图1-6右下角的Next。出现图1-7所示的系统镜像选择界面。
图1-7 系统镜像选择界面
建议读者选择Nougat x86系统镜像。也就是说,我们后面要分析的ART虚拟机将以x86 CPU为平台。
为什么选择x86平台?
工作用的台式机或笔记本主要是x86平台。所以,模拟器运行x86系统镜像的速度非常快。笔者之前尝试过使用arm平台,但模拟器运行的速度较慢。另外,根据上一节笔者统计的代码量可知,6个CPU平台总汇编代码的有效代码行数/总有效代码行数大概为6.02%,平均每个CPU平台的汇编代码行数才占总代码行数的1%左右。从这一点可以看出,汇编代码虽然重要,但它不会影响虚拟机学习。值得注意的是,Android SDK从8.0开始就不再提供ARM平台的模拟器镜像文件。
虚拟设备准备就绪后,读者可以启动它。这时,这个虚拟设备运行的是官方提供的镜像。
1.2.3.2 自制系统镜像
现在,我们有了Android源码、虚拟设备和官方下载的镜像文件。接下来需要编译Android源码以生成一个系统镜像文件,然后用这个系统镜像文件来启动虚拟设备。如此,就达到了让虚拟设备运行我们定制的系统镜像的目标。
编译系统的步骤如下。
[自制系统镜像]
cd android-7.0 #进入源码目录 . build/envsetup.sh #初始化AOSP编译环境 lunch #选择编译目标,执行后的结果如图1-8所示
图1-8 lunch命令执行的结果
执行lunch命令后,会显示如图1-8所示的内容,里边是各种不同的目标设备。请读者选择第8项(下面将介绍第8项的来历)。它表示要编译设备类型为"innost"的设备,该设备使用的CPU为x86,编译类型为userdebug。接着看下一步。
[自制系统镜像]
#执行下面的命令 make systemimage #编译系统镜像 #最终生成的系统镜像文件路径为 #out/target/product/innost_x86/system.img #这就是我们编译得到的系统镜像
最后,让模拟器使用我们编译得到的系统镜像文件,方法如下。
#当前在android-7.0目录下。假设android sdk位于 #~/workspace/android/android-aosp-sdk中,下面的命令将启动emulator,其中: #-avd参数用于指明虚拟设备名,参考图1-4,我们选择的是innost-7.0这个虚拟设备 #-system参数指明系统镜像的路径,我们使用自己编译得到的系统镜像文件 ~/workspace/android/android-aosp-sdk/tools/emulator \ -avd innost-7.0 -nojni -writable-system \ -system `pwd`/out/target/product/innost_x86/system.img
由于本书的目标是研究ART虚拟机,所以,我们自己编译的系统镜像并不需要包含太多的应用程序,只要保证系统启动必需的几个核心应用程序即可。为此,笔者在源码根目录/device下新增了一个名为innost的设备类型。图1-9展示了该目录下的文件。
图1-9展示了innost设备类型下包含的文件。当把这些准备好后,我们执行如下命令时才能出现图1-8中的第7和第8项。
. build/envsetup.sh lunch #将出现图1-7中的innost设备
读者可从笔者分享的链接中下载如图1-9所示的innost设备目录文件。本书所有资源的下载说明见1.4节的内容。
提示 如果读者下载了笔者分享的Android 7.0源码的话,device目录下已经包含了innost设备目录的文件。