前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Dalvik,ART与ODEX简析

Dalvik,ART与ODEX简析

作者头像
Anymarvel
发布2018-10-22 11:34:24
1.5K0
发布2018-10-22 11:34:24
举报
文章被收录于专栏:Android开发实战Android开发实战

如果你有这样的问题: 1.Dalvik和ART的区别 2.DEX在Dalvik转化为ODEX和ART中转化为ODEX的过程有上面区别 3.multidex在dalvik上起作用,ART上使用的也是multidex么(如果不是的话在application中写入multidex.install会对apk启动造成影响么)

如果你比较“懒”,,懒得看老罗的源码分析,,,长篇大论 请“简要”看完以下“简要”内容

一: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的过程

简化流程如下:

打包安装运行简化流程.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字节码进行优化:

代码语言:javascript
复制
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虚拟机的过程分析

代码语言:javascript
复制
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的,跟虚拟机关系不大。

代码语言:javascript
复制
@Override
    attachBaseContext(……) {
    super.attachBaseContext(base);
    MultiDex.install(this);
}

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

代码语言:javascript
复制
 Set var2 = installedApk;
 synchronized(installedApk) {                  
 String apkPath = e.sourceDir;                  
 if(installedApk.contains(apkPath)) {                        
       return;
    }

所以multidex在ART上不会影响程序的逻辑,它和ART没有关系~。。。。 multidex源码分析:MultiDex安装过程源码分析

小结:

从安装过程上来看 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启动、运行更快 减少每次启动的编译增加电池续航 存储占用更大 安装时间更长

复制粘贴+理解,,,希望以后忘了能回来看看~!~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Android历练记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一:Dalvik和ART的区别
  • 二.在不同平台DEX转化为ODEX的过程
  • 三.oat文件格式
  • 四.multidex加载odex,multidex和oat的关系
    • 小结:
    相关产品与服务
    腾讯云代码分析
    腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档