首页
社区
课程
招聘
[原创][原创]dalvik虚拟机启动及运行原理的研究
发表于: 2018-1-29 15:21 10243

[原创][原创]dalvik虚拟机启动及运行原理的研究

2018-1-29 15:21
10243

这个称作孵化器的进程由init进程创建,之后创建了SystemServer(其中包括包管理服务,应用程序组件管理服务)。 
当我们需要通过应用程序组件管理服务(ActivityManagerService)创建新进程时,会通过Socket进程间通信机制,通知Zygot进程为应用程序创建一个新的进程。其实就是把启动后的dalvik赋值一份到新进程。

前面的Zygote在启动时,会运行AndroidRuntime类的成员函数start. 
这里有个关键java的入口,java就是从这里开始运行的,com.android,internal.os.Zygoteinit.虚拟机也是从这里开始运行的。这个类的main退出时,也就是Zygote进程准备要退出的时候。

AndoridRuntime类里启动虚拟机的函数。 
这里包含了很多启动参数,运行模式等

这里创建了虚拟机的实例,JavaVMExt对象,创建JNI环境(JNIEnvExt对象),初始化虚拟机实例(dvmStartup)。 
设置当前线程执行状态,返回调用者JavaVMExt和JNIExt,分别通过输出参数p_vm和p_env.

JavaVMExt成员变量funcTable保存了虚拟机实例的函数表。

JNIEnvExt用来在java和C/C++函数之间相互调用。并且多个线程对应的JNIEntExt组成了一个列表,第一个JINIExt表示的是主线程。

这里会创建JNI环境,还有个JNINativeInterface的结构体,本地接口表。当我们需要在C/C++代码中 调用java函数,就要用到这个本地接口表。 
findClass寻找java类,GetMethodID获得java类的成员函数,CallObjectMethod函数间接调用之。GetFeildID获得java类成员变量.当然还可以注册反注册jNI方法到java类中。

初始化虚拟机 
我这里关注下 
1.dvmClassStartup ,用来初始化类加载器。这里是加载JAVA用的。dalvik/vm/oo/Class.c 
2.dvmNativeStartup 加载so库加载 表,用来描述当前进程那些SO文件已经被加载过了。 dalvik/vm/Native.c 
3.dvmInternalNativeStartup 初始化内部native函数表。

正如我们上面所得,得到JNIEnv的环境变量后,我们就可以进行函数调用了。我们通过这个结构体的成员变量function来实现函数的调用。 
1.对应的java调用利用CallStaticVoidMethod(其实是由dvmCallMethodV实现的)函数执行参数clazz和methodID所描述的Java代码。 
2.dvmCallMethodV这个函数其实是java和native都可以执行的,但是会通过检测method 的描述函数来判断是否是JNI方法,如果是就执行native,否则执行java函数。 
3.dvmCallMethodV在执行java的时候还会调用一个dvmInterpret的函数,这个函数有几种模式,可以在初始化的时候确定。而dvmInterpret就是我们在执行Java过程中的解释器。

以Zygote进程为例,Dalvik虚拟机解释器就是以com.android.internal.os.ZygoteInit类 的静态成员函数main为入口点执行的,然后在Socket循环等待ActivityManagerService服务向它发送创建新的应用程序进程的请求。 
而以Android应用程序进程为例,Dalvik虚拟机解释器就是以android.app.ActivityThread类的静态成员函数main为入口点执行,然后在消息队列上进行循环,用来等待和处理主线程的消息。

systemlaod——–nativelaod———-Dalvik_java_lang_runtime_nativeLoad(C++层)——-dvmaLoadNativeCode—–dlopen

然后就是native层函数对应java层的调用方式标记。是用jniRegisterNativeMethods(调用了函数表中RegisterNative)的实现。

为了进一步对虚拟机有较深的理解,我这里把xpose框架的各种文档也查看和阅读了下。总结成如下的图: 
这里把流程图分割成了三份,作的图有点大了。 
简单说xpose的框架就是核心的替换虚拟机中的执行过程中的java调用过程,如何实现这个过程? 
1.是通过替换系统的app_process可执行文件实现虚拟机中函数的执行地址替换。 
2.把java函数替换到native后通过调用XposedBridge.jar来实现自定义函数的调用和原函数的调用 
3.具体native到java的实现大致如图2 
XposeInstall是用来实现安装整个xpose框架的。 
XposedMods:管理自己开发的插件app. 



[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (3)
雪    币: 2731
活跃值: (1651)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
非常赞的分享。  如果可以可以连接代码什么的  ,方便其他人继续投入
2018-2-2 17:24
0
雪    币: 1319
活跃值: (1335)
能力值: ( LV8,RANK:140 )
在线值:
发帖
回帖
粉丝
4
这就是android源码学习,没其他代码了
2018-2-2 19:23
0
游客
登录 | 注册 方可回帖
返回
//