5. Android虚拟机和类加载机制

Android 虚拟机是什么?
DalvikART(Android Runtime)

扩展知识

Dalvik是运行的.dex文件,一个.dex文件可以包含多个.class文件,也就是说一个.dex是包含多个类的
JVM运行的是.class文件,一个.class文件只包含一个类

寄存器是什么?
寄存器是CPU中的组成部分,是有存储容量的高速存储部件,用来暂存指令、数据和地址.

Dalvik和ART
Dalvik虚拟机执行的是dex字节码文件,解释执行.支持JIT即时编译(Just In Time),在程序的运行过程中进行选择热点代码(经常执行的代码)进行编译或者优化

Dalvik下安装应用时,会执行一次优化,将dex字节码文件优化生成odex文件.

ART虚拟机运行的是机器码

应用程序(apk)在安装的时候,ART使用设备(手机)自带的dex2oat工具来编译应用程序(apk),dex文件中的文件就会被编译成机器码

Andorid N的运作方式

  • 应用在安装时不进行AOT编译,运行过程中解释执行,对经常执行的方法进行JIT,经过JIT(即时编译)编译的方法将会记录到Profile配置文件中去
  • 当设备闲置和充电时,编译守护进程会运行,根据profile文件对常用的代码进行AOT(通过dex2aot工具编译成机器码)编译.待下次运行时直接使用(机器码)

Android中的各种类加载器

  • ClassLoader (超类)
  • BootClassLoader (用于加载Android Framework层class文件,ClassLoader的内部类)
  • BaseClassLoader (下面两个类的父类)
  • PathClassLoader (Android应用程序的类加载器)
  • DexClassLoader (额外提供的动态类加载器)

ClassLoader加载类的流程和双亲委托机制

  1. 双亲委托机制

    如果某个类加载器在加载类时,首先将加载任务委托给父类加载器,一次递归,如果父类可以完成加载任务,就成功返回;
    如果父类加载器无法完成任务加载或者没有父类加载器,才自己去加载
    双亲委托机制的作用是什么?

    • 避免重复加载,当父类已经加载了该类的时候,子classLoader就没有必要重复加载一次
    • 安全性考虑,防止核心API被随意篡改

代码加载流程 ClassLoader.java

protected Class<?> loadClass(String name, boolean resolve)
       throws ClassNotFoundException
   {
           // First, check if the class has already been loaded
           Class<?> c = findLoadedClass(name);
           if (c == null) {
               try {
                   //TODO tangkun 这里的parent是BootClassLoader
                   if (parent != null) {
                       c = parent.loadClass(name, false);
                   } else {
                       c = findBootstrapClassOrNull(name);
                   }
               } catch (ClassNotFoundException e) {
                   // ClassNotFoundException thrown if class not found
                   // from the non-null parent class loader
               }

               if (c == null) {
                   // If still not found, then invoke findClass in order
                   // to find the class.
                   c = findClass(name);
               }
           }
           return c;
   }
  1. ClassLoader加载类的流程?Apk加载对应的class文件

    apk——>通过dex文件路径——>关联到PathClassLoader(父类重新了loadClass方法,父类是BaseDexClassLoader)——>DexPathList ——>Element[]数组(遍历)——>Element元素——>DexFile ——>loadClassBinaryName()方法——>拿到这个class对象

热修复原理是什么?
在应用启动阶段,也就是在我们自定义的Application中,利用Android类加载机制,也就是PathClassLoader加载我们已经修复了bugdex文件(这个修复了bugdex文件可以放在sd卡或者应用的私有目录中(data/data)),然后利用反射技术调用PathClassLoadermakeElement方法生成修复bugElement数组,再将修复bug的数组插入到原来的Element数组的前面,每次在加载类的时候,就会先加载我们修复bugdex文件,最终达到热修复的目的.

如何生成已经修复的dex文件?
将已经修复了bug的代码的类通过编译(make project)生成class文件,然后将class文件打包生成dex文件,这里需要用到sdkdx.bat工具进行打包,这个工具可以同时打包多个class文件,或者将多个class文件打包成jar包,然后通过打包工具一次性打包生成dex文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值