您现在的位置:主页 > 技术中心 > 编程开发 > 移动开发 > Android

Android——Dalvik虚拟机运行ZygoteInit类

来源:网络 责任编辑:admin 发表时间:2013-07-02 06:40 点击:

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

从上一节可以知道Dalvik虚拟机入口点和创建虚拟机的函数,这一节继续分析运行时类调用虚拟机的代码片段,需要搞清楚怎么样运行JAVA的ZygoteInit类,Dalvik虚拟机又提供什么样的接口调用。运行时类代码如下:

/* start the virtual machine */

if (startVm(&mJavaVM, &env) != 0)

goto bail;

这一段是创建虚拟机,并准备好所有运行dex代码的环境。

 

/*

* Register android functions.

*/

if (startReg(env) < 0) {

LOGE("Unable to register all android natives ");

goto bail;

}

这一段是注册所有android提供的本地方法,所谓的本地方法,其实是相对于JAVA里定义的方法,比如像C或C++等提供二进制运行的方法。

 

 

/*

* We want to call main() with a String array with arguments in it.

* At present we only have one argument, the class name. Create an

* array to hold it.

*/

jclass stringClass;

jobjectArray strArray;

jstring classNameStr;

jstring startSystemServerStr;

 

stringClass = env->FindClass("java/lang/String");

assert(stringClass != NULL);

strArray = env->NewObjectArray(2, stringClass, NULL);

assert(strArray != NULL);

classNameStr = env->NewStringUTF(className);

assert(classNameStr != NULL);

env->SetObjectArrayElement(strArray, 0, classNameStr);

startSystemServerStr = env->NewStringUTF(startSystemServer ?

"true" : "false");

env->SetObjectArrayElement(strArray, 1, startSystemServerStr);

这一段代码主要作用是把类型参数className转换为虚拟机里调用方法的参数,就是转为 strArray数组表示,同时可以添加多个参数。

 

 

/*

* Start VM. This thread becomes the main thread of the VM, and will

* not return until the VM exits.

*/

jclass startClass;

jmethodID startMeth;

 

slashClassName = strdup(className);

这一行代码是拷贝类名称。

 

for (cp = slashClassName; *cp != ; cp++)

if (*cp == .)

*cp = /;

这一段代码是把类名称 com.android.internal.os.ZygoteInit转换为 com/android/internal/os/ZygoteInit,为什么要转换这样的方式呢?其实仔细思考一下,发现这不正是linux下的目录表示方式吗?是的,就是把类的点连接符变换为目录方式,这要就可以到相应的目录里找到执行的代码文件。

 

LOGD("caijs add: JavaVM load class %s ", slashClassName);

startClass = env->FindClass(slashClassName);

if (startClass == NULL) {

LOGE("JavaVM unable to locate class %s ", slashClassName);

/* keep going */

} else {

这一段代码主要通过类目录结构com/android/internal/os/ZygoteInit,查找到类的代码,查找到了就保存在startClass变量里。到这里,已经接触到Dalvik虚拟机提供了最重要的一个方法,它就是 FindClass方法接口,这个接口比较强大,只要提供类的目录结构,就可以找到相应的执行代码,这样就可以找类相关的方法入口,才可以给虚拟机解释器执行。因此,后面要好好了解和分析这个接口的实现。

 

 

startMeth = env->GetStaticMethodID(startClass, "main",

"([Ljava/lang/String;)V");

if (startMeth == NULL) {

LOGE("JavaVM unable to find main() in %s ", className);

/* keep going */

} else {

这一段代码是查找方法入口点的ID。主要就是在前面找到的类代码基础之上,然后通过方法名称“main”调用GetStaticMethodID接口,查找到方法的ID。这个方法ID是给后面虚拟机运行这个方法使用的,因为一个类里有很多方法,每个方法都有一个ID,只有通过这个ID才可以找到相应的方法来运行。在这段代码里,有一个特别的地方,就是 GetStaticMethodID方法最后一个参数“([Ljava/lang/String;)V”。这个参数是一个字符串,但内容排列比较奇怪,其实它是一种对函数返回值和参数的编码。这种编码叫做JNI字段描述符(Java Native Interface Field Descriptors)。

 

 

LOGD("caijs add: JavaVM find main() in %s ", className);

env->CallStaticVoidMethod(startClass, startMeth, strArray);

这一行代码主要调用虚拟机的接口CallStaticVoidMethod 来运行 com.a

    相关新闻>>

      发表评论
      请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
      评价:
      表情:
      用户名: 验证码:点击我更换图片

      推荐热点

      • Android 完全退出程序
      • 原创:Android应用开发-Andorid歌词秀,含源码
      • android 屏幕保护
      • Android手机软件汉化教程---第四课 dex文件汉化
      • 众多Android 开源项目推荐,给力工作给力学习
      • Android Audio代码分析4
      • Android得到已安装的应用程序信息!
      • MIUI:10个亮点及5处不足
      • Android成长的幕后推手:工程师鲁宾
      ?? - ?? - ÝřŝžľŘÝź - TAGąęÇŠ - RSSśŠÔÄ - ??
      Copyright © 2004-2024 上海卓卓网络科技有限公司