前段时间热修复这个词非常火,当时只是大体看了一下,今天抽空好好看了一下具体原理.

什么是热修复?

简单的说就是用户不用重新下载一个新的apk安装,而是直接下载一个补丁包,通过补丁来替换一些出现bug的类, 当然下载补丁的过程用户一般是感觉不到的,表面上看是直接修复了bug.

原理

类似与插件开发,关于插件开发原理,看这篇Android插件原理剖析,其中介绍了一下java中的类加载器和android中的类加载器. 热修复就是利用android中的 DexClassLoader类加载器,动态加载补丁dex,替换有bug的类

已有的热修复解决方案:
- https://github.com/dodola/HotFix
- https://github.com/jasonross/Nuwa
- https://github.com/bunnyblue/DroidFix

这几个库的原理都类似,具体描述可以查看这篇安卓App热补丁动态修复技术介绍.

切入点

想修复方法? 方法在哪里? 方法都包含在类中. 类在哪里? 类被包含在dex中,而

最根本的来源是下面这段代码:

public Class findClass(String name) {    for (Element element : dexElements) {        DexFile dex = element.dexFile;        if (dex != null) {            Class clazz = dex.loadClassBinaryName(name, definingContext);            if (clazz != null) {                return clazz;            }        }    }    return null;}

可以看出呢,BaseDexClassLoader中有个pathList对象,pathList中包含一个DexFile的集合dexElements,而对于类加载呢,就是遍历这个集合,通过DexFile去寻找,一个ClassLoader可以包含多个dex文件,每个dex文件是一个Element,多个dex文件排列成一个有序的数组dexElements,当找类的时候,会按顺序遍历dex文件,然后从当前遍历的dex文件中找类,如果找类则返回,如果找不到从下一个dex文件继续查找。

简单来说: 首先找到pathList对象,然后通过反射改变dexElements数组.
但是遇到的以下问题: 也就是类被打上了 CLASS_ISPREVERIFIED 标志

java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation

根据QQ空间的文章, 这个错误是因为虚拟机加载类的时候, 当一个类中的直接方法(Direct Method)来自与同一个dex中,那么这个类就会被加上 CLASS_ISPREVERIFIED 标志, 再次通过类加载器加载会出现上面的错误.

解决方案: 在需要加载的类中,引用一个别的dex中的类.这样这个类就不会被加上 CLASS_ISPREVERIFIED 标志了,然后就可以再次加载了. 上面一个开源库的普遍方案就是在类的 默认构造方法 上面添加一个其他dex的引用.

总结

于是总体步骤如下:

  1. 可能出现bug的类中,引用一下别的dex中的类.
  2. 因为1中引用了别的dex,需要先将别的dex加载进来.
  3. 现在可以替换bug的类了,加载补丁,通过反射将补丁中的dex放到pathList对象的dexElements数组的前面,完成打补丁.

其中两个注意点:
- 防止类被加上 CLASS_ISPREVERIFIED 标志(通过修改类默认构造方法)
- 生成补丁dex(通过dx工具)

参考文章:
- DexClassLoader
- PathClassLoader
- 安卓App热补丁动态修复技术介绍
- Android插件原理剖析
- Android 热补丁动态修复框架小结

更多相关文章

  1. Android(安卓)加载本地图片(文件管理器中的图片墙)
  2. Android(安卓)开发技术选型(博客,新闻,阅读类)
  3. Android常用技术-热修复解析
  4. System.Lazy延迟加载 在很多情况下,有些对象需要在使用时加载或根
  5. 手把手教你用android studio创建第一个安卓程序加载html5页面(一)
  6. Android热修复技术总结
  7. 深度剖析 | 阿里热修复如何精简优化补丁资源?
  8. Android动态加载第三方APK的View研究过程
  9. Android中插件开发篇之----类加载器

随机推荐

  1. 与Android有关的三起诉讼事件
  2. Android常见错误之[email protected
  3. Android Root原理分析及防Root新思路
  4. android拨打电话流程分析
  5. Android获取Apk文件图标信息
  6. Android内核和驱动的详细介绍
  7. Android材料设计之材料主题
  8. 巧用Android图片资源,打造更精致的APP
  9. Android自定义视图三:给自定义视图添加“
  10. 【原创】Android 耗电信息统计服务——Ba