9.2 Dalvik虚拟机相关的可执行程序
在Android源码中,大家会发现好几处和Dalvik这个概念相关的可执行程序,正确区分这些可执行程序的区别将有助于理解Framework内部结构。这些可执行程序的名称和源码路径如表9-1所示。
下面将分别介绍这些可执行程序的作用。
9.2.1 dalvikvm
当Java程序运行时,都是由一个虚拟机来解释Java的字节码,它将这些字节码翻译成本地CPU的指令码,然后执行。对Java程序而言,负责解释并执行的就是一个虚拟机,而对于Linux而言,这个进程只是一个普通的进程,它与一个只有一行代码的Hello World可执行程序无本质区别。所以启动一个虚拟机的方法就跟启动任何一个可执行程序的方法是相同的,那就是在命令行下输入可执行程序的名称,并在参数中指定要执行的Java类。
dalvikvm的作用就是创建一个虚拟机并执行参数中指定的Java类,下面以一个例子来说明该程序的使用方法。
首先新建一个Foo.java文件,如以下代码所示:
class Foo {
public static void main(String[] args) {
System.out.println("Hello dalvik");
}
}
然后编译该文件,并生成Jar文件,如以下代码所示:
$ javac Foo.java
$ PATH=/Users/keyd/android/out/host/darwin-x86/bin:$PATH
$ dx --dex --output=foo.jar Foo.class
dx工具的作用是将.class转换为dex文件,因为Dalvik虚拟机所执行的程序不是标准的Jar文件,而是将Jar文件经过特别的转换以提高执行效率,而转换后的文件就是dex文件。dx工具是Android源码的一部分,其路径是在out目录下,因此在执行dx之前,需要添加该路径。
dx执行时,--output参数用于指定Jar文件的输出路径,注意该Jar文件内部包含已经不是纯粹的.class文件,而是dex格式文件,Jar仅仅是zip包。
生成了该Jar包后,就可以把该Jar包push到设备中,并执行,如以下代码所示:
$ adb push foo.jar /data/app
$ adb shell dalvikvm -cp /data/app/foo.jar Foo
Hello dalvik
以上命令首先将该Jar包push到/data/app目录下,因为该目录一般用于存放应用程序,接着使用adb shell执行dalvikvm程序。dalvikvm的执行语法如下:
dalvikvm -cp 类路径 类名
从这里也可以感觉到,dalvikvm的作用就像在PC上执行Java程序一样。
9.2.2 dvz
dvz的作用是从zygote进程中孵化出一个新的进程,新的进程也是一个Dalvik虚拟机。该进程与dalvikvm启动的虚拟机相比,区别在于该进程中已经预装了Framework的大部分类和资源,下面以一个具体的例子来看dvz的使用方法。
首先在Eclipse下新建一个APK项目,包名称为com.haiii.android.helloapk,默认的Activity名称为Welcome,其内容如下:
public class Welcome extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public static void main(String[] args) {
System.out.println("Hello dalvik");
}
}
该段代码是大家非常熟悉的Hello Android代码,唯一的区别在于增加了一个static main()函数,因为该函数将作为Welcome类的入口。
接下来,将生成的APK文件push到/data/app目录下,然后运行Welcome类,如以下代码所示:
# dvz -classpath /data/app/HelloApk.apk com.haiii.android.helloapk.Welcome
Hello dalvik
In mgmain JNI_OnLoad
dvz的语法如下:
dvz -classpath 包名称 类名
讲到这里,有的读者可能猜想,是否可以在main()函数内部构造一个Welcome对象,从而可以达到运行该APK的目的?答案是否定的,因为Welcome类并不是该应用程序的入口类,在后面的章节中,大家将看到,一个APK的入口类是ActivityThread类,Activity类仅仅是被回调的类,因此不可以通过Activity类来启动一个APK,dvz工具仅仅用于Framework开发过程的调试。
本文选自《Android内核剖析 》一书
图书详细信息:http://blog.chinaunix.net/space.php?uid=13164110&do=blog&id=2897431