Android基础知识学习记录(一)

一、说一说Android的虚拟机DVM与ART

在说DVM与ART之前,要说说与JVM的一个区别,前者是基于寄存器实现的,后者是基于栈实现的。

1.DVM:

Dalvik是Google公司自己设计用于Android平台的Java虚拟机。支持已转换为.dex(Dalvik Executable)格式的Java应用程序的运行,.dex格式是专为Dalvik应用设计的一种压缩格式,适合内存和处理器速度有限的系统。

2.ART:

ART是Android Run Time即Android运行时的简称, Android 4.4 中引入的一个开发者选项,也是 Android 5.0 及更高版本的默认模式。与DVM比较,它会在应用程安装时会做一个Ahead -Of-Time(AOT)也叫做预编译的操作,会将字节码预编译成机器码(oat),这样虽然在安装时增加了安装时间,但是由于在执行时免去了字节码转机器码的过程,因此可以减少CPU的消耗进而节能,更重要的是提升了程序的运行效率以及启动速度。

二、类加载器

我们程序的执行依赖于虚拟机是无疑的,那我们的代码是怎样加载到虚拟机中的呢,这里就需要引入类加载器这个概念了,类加载器完成的主要工作就是将我们的dex文件中的.class文件加载到虚拟机中,进而实现我们程序的执行,为了加载不同类型的类,虚拟机提供了不同的类加载帮助我们实现类的加载,下面就对几种类加载器分别进行一下说明。

1.BootClassloader

用于加载Android FrameWork层Class文件

2.BaseDexClassloader

是PathClassloader以及DexClassloader的父类

3.PathClassloader

用于应用程序类加载器,可以加载指定的dex,以及jar、zip、apk中的classes.dex

4.DexClassloader

用于加载指定的dex,以及jar、zip、apk中的classes.dex

说了一下Android系统提供给我们的类加载器,那究竟这些类加载器是怎样实现将我们的类加载到虚拟机中的呢,下面就详细说一下PathClassloader,关于BootClassloader我们实现的代码不需要关心这些,就不说了,DexClassloader与我们的PathClassloader是类似的都继承于同一父类,.loadclass也都是调用父类的,所以就也不说了。

那下面就看看父类的loadclass方法

Android基础知识学习记录(一)_第1张图片

从上图可以看到我们先是调用父亲的加载方法,如果没有再自己加载,我们称这种加载方式为双亲委托机制,即自己先不加载,先去找父类去加载,而父亲也是这样,自己先不加载先找自己的父亲去加载,如果没有再自己加载,如果最后到当前的类机载器还是没有加载到就会抛出一个我们都遇到的一个异常ClassNotFoundException,而在记载的流程之前我们也可以看到在加载之前有一个判断及判断这个类是否有被加载过,如果加载过就返回了,即相同的类只会被加载一次到虚拟机中,那再往下看findClass方法,我们最终会看到一个DexPathList类型的属性,而这个类中存在一个Element类型的数组,而实现类的记载其实就是在于这个Element,我们可以看到如下代码

Android基础知识学习记录(一)_第2张图片

它是通过遍历这个Element类型的数组中的每一个元素去完成类的加载的,如果找到了就返回,没有继续去遍历,那Element类型的对象在加载类时是怎样加载的呢?可以继续往下看如下代码

Android基础知识学习记录(一)_第3张图片

Android基础知识学习记录(一)_第4张图片

我们可以看到其中的关键点是Element中的DexFile,关键点就是使用DexFile进行的类的加载,而这个类的加载是一个Native方法。

三、基于Java与类加载器中的DexFile实现的热更新实现的原理

我们从类的加载原理中可以看到有一个Element类型的数组,类的加载是通过遍历这个数组,如果我们的程序中某个类出现了问题,可以将这个类编译成dex文件,并将其添加到Element类型的数组的前面,我们就可以完成了代码的热更新。

你可能感兴趣的:(Android的类加载)