如何进行Dalvik,ART与ODEX简析

这期内容当中小编将会给大家带来有关如何进行Dalvik,ART与ODEX简析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

创新互联是一家专业提供镇沅企业网站建设,专注与成都网站建设、网站制作、HTML5建站、小程序制作等业务。10年已为镇沅众多企业、政府机构等服务。创新互联专业的建站公司优惠进行中。

一:Dalvik和ART的区别

Dalvik: Dalvik是Google公司自己设计用于Android平台的Java虚拟机它可以支持已转换为 .dex(即Dalvik Executable)格式的Java应用程序的运行,.dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。执行的是字节码,它是依靠Just-In-Time (JIT)机制去解释字节码
ART:即Android Runtime,google为了替代Dalvik专门为Android研发的。Android KK为开发者推出,L版本正式上线。比替代品更高效省电,执行的是本地机器码(也就是linux的ELF文件格式),依靠Ahead-Of-Time (AOT)机制

二.在不同平台DEX转化为ODEX的过程

简化流程如下:

如何进行Dalvik,ART与ODEX简析

打包安装运行简化流程.png

这里参考的是

Android ART运行时无缝替换Dalvik虚拟机的过程分析

http://blog.csdn.net/luoshengyang/article/details/18006645

android安装过程源码分析:

Android应用程序进程启动过程的源代码分析

http://blog.csdn.net/luoshengyang/article/details/6747696

简单来说,就是Android系统通过PackageManagerService来安装APK,在安装的过程,PackageManagerService会通过另外一个类Installer的成员函数dexopt来对APK里面的dex字节码进行优化:

public final class Installer {  
    ......  

    public int dexopt(……) {  
        StringBuilder builder = new StringBuilder("dexopt");  
        builder.append(' ');  
        builder.append(apkPath);  
        builder.append(' ');  
        builder.append(uid);  
        builder.append(isPublic ? " 1" : " 0");  
        return execute(builder.toString());  
    }  

    ......  
}

这个函数定义在文件frameworks/base/services/java/com/android/server/pm/Installer.java中。Installer通过socket向守护进程installd发送一个dexopt请求,这个请求是由installd里面的函数dexopt来处理的。详细过程请移步Android ART运行时无缝替换Dalvik虚拟机的过程分析

int dexopt(const char ……

函数定义在frameworks/native/cmds/installd/commands.c中 函数dexopt首先是读取系统属性persist.sys.dalvik.vm.lib的值,接着在/data/dalvik-cache目录中创建一个odex文件。这个odex文件就是作为dex文件优化后的输出文件。再接下来,函数dexopt通过fork来创建一个子进程。如果系统属性persist.sys.dalvik.vm.lib的值等于libdvm.so,那么该子进程就会调用函数run_dexopt来将dex文件优化成odex文件。另一方面,如果系统属性persist.sys.dalvik.vm.lib的值等于libart.so,那么该子进程就会调用函数run_dex2oat来将dex文件翻译成oat文件,实际上就是将dex字节码翻译成本地机器码,并且保存在一个oat文件中。
函数run_dexopt通过调用/system/bin/dexopt来对dex字节码进行优化,而函数run_dex2oat通过调用/system/bin/dex2oat来将dex字节码翻译成本地机器码。注意,无论是对dex字节码进行优化,还是将dex字节码翻译成本地机器码,最终得到的结果都是保存在相同名称的一个odex文件里面的,但是前者对应的是一个dey文件(表示这是一个优化过的dex),后者对应的是一个oat文件(实际上是一个自定义的elf文件,里面包含的都是本地机器指令)。通过这种方式,原来任何通过绝对路径引用了该odex文件的代码就都不需要修改了。

三.oat文件格式

借助罗大神的图我们可以知道,OAT文件本质上是一个ELF文件,因此在最外层它具有一般ELF文件的结构,例如它有标准的ELF文件头以及通过段(Section)来描述文件内容。

OAT文件包含有两个特殊的段oatdata和oatexec,前者包含有用来生成本地机器指令的dex文件内容,后者包含有生成的本地机器指令,它们之间的关系通过储存在oatdata段前面的oat头部描述。

APK安装过程中生成的OAT文件的输入只有一个DEX文件,也就是来自于打包在要安装的APK文件里面的classes.dex文件。实际上,一个OAT文件是可以由若干个DEX生成的。这意味着在生成的OAT文件的oatdata段中,包含有多个DEX文件。详细分析请移步Android运行时ART加载OAT文件的过程分析

四.multidex加载odex,multidex和oat的关系

MultiDex在dalvik虚拟机上的简要安装过程:
将/data/app/apkName.apk路径下解压得到的classes2.dex, …, classesN.dex,依次写入到/data/data/pkgName/code_cache/secondary-dexes/apkName.apk.classes2.zip等zip文件的classes.dex中,并返回这个zip列表。然后针对这个zip列表执行安装过程,具体过程是,将这个要安装的zip列表加入BaseDexClassLoader的pathList实例的dexElements数组中,其中会针对各dex文件进行dex2opt优化。一旦加入到了dexElements数组中,程序启动的时候,ClassLoader会加载dexElements数组中的元素,从而实现multi dex的安装。

上面提到OAT文件可以由若干个dex生成,也就是不需要multidex去进行安装,但是multidex是application中
进行Install的,跟虚拟机关系不大。

@Override
   attachBaseContext(……) {    super.attachBaseContext(base);    MultiDex.install(this); }

在install函数中在执行从提取dex文件列表前会做一些校验操作,其中包含检查APK是否已安装,若APK已安装,则不进行后续操作。检查SDK版本号,版本号大于20不能保证MultiDex可正常Work

 Set var2 = installedApk;
 synchronized(installedApk) {                  
 String apkPath = e.sourceDir;                  
if(installedApk.contains(apkPath)) {                        
      return;    }

所以multidex在ART上不会影响程序的逻辑,它和ART没有关系。

从安装过程上来看
Java的代码实际上需要两次“转换”才可以在android设备上运行
一.PC端:.class->.dex->.apk
二.phone:dex->odex

区别在于第二步。
ART : .dex->.odex(机器码)(AOT  Ahead-Of-Time)
Dalvik: .dex->.odex(字节码)(JIT Just-In-Time)
机器码可直接执行,而字节码每次启动都需要执行将优化过的odex字节码再转换成机器码

ART优缺

系统性能大幅提升
App启动、运行更快
减少每次启动的编译增加电池续航
存储占用更大
安装时间更长

上述就是小编为大家分享的如何进行Dalvik,ART与ODEX简析了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联行业资讯频道。


网站栏目:如何进行Dalvik,ART与ODEX简析
路径分享:http://cdiso.cn/article/ghoege.html

其他资讯