Android热修复原理

来源:互联网 发布:杭州软件测试培训班 编辑:程序博客网 时间:2024/05/16 10:30

  最近使用到Android热修复相关的技术,然后查看了很多博客,源码,大概了解了Android实现热修复的原理,如有错误,还请大家留言指正

  首先来了解一下为什么要使用热修复技术。 当一个应用发布到各个应用市场之后,突然发现了一个严重bug需要进行紧急修复,这时候公司各部门就都会忙得焦头烂额:包括重新打包App、测试、然后再向各个应用市场和渠道换包、提示用户升级、用户下载、覆盖安装。有时候仅仅是为了修改了一行代码,也要付出巨大的成本去进行换包和重新发布。 这么复杂的步骤,肯定不是我们开发者想要看到的。 所以这时候就会用到我们今天要提的热修复技术。

  简单的概括一下热修复的原理,就是把多个dex文件塞入到app的classloader之中,这里的classloader的功能主要是对类的请求提供服务,当JVM需要某类时,它根据名称向ClassLoader要求这个类,然后由ClassLoader返回这个类的class对象。 但是android dex拆包方案中的类是没有重复的,如果新的classes1.dex和旧的classes.dex中有重复的类,当用到这个重复的类的时候,系统会选择哪个类进行加载呢?   看一下代码:

  

  一个classloader中包含多个dex文件,多个dex文件排列成一个有序的数组dexElements,当找类的时候,会按顺序遍历dex文件,然后从当前遍历的dex文件中找类,如果找到目标类则返回,如果找不到就从下一个dex文件继续去查找。

并且理论上,如果在不同的dex中有相同的类存在,那么会优先选择排在前面的dex文件中的那个类,通过这里我们就能够想到Android热修复的原理,就是将改正问题后的类打包成一个patch.dex文件,然后让这个patch.dex拍到dexElements的前边,这样,在遇到相同类时,就会去加载我们修复好的那个类文件。

     但是当你修改后的这个类,包含其他类的引用,但是你修改的这个类,以及被引用者并不在同一个dex中时,即两个相关联的类在不同dex时,就会产生错误,原因就是,引用者(被修改的类)被打上了CLASS_ISPREVERIFIED标志,那么就会进行dex的校验。 

    如果想要实现补丁方案,就要从这个方面入手,防止类被打上CLASS_ISPREVERIFIED标识,可以使用以下解决方法:

在每个类的构造方法中添加这句代码:

if (ClassVerifier.PREVENT_VERIFY) {    //在这里获取到其他类的引用对象}  这句代码是为了实现被打包成单独的hack.dex,这样当安装apk的时候,classes.dex内的类都会引用一个在不相同dex中的引用类,这样就防止了类被打上CLASS_ISPREVERIFIED的标志了,只要没被打上这个标志的类都可以进行打补丁操作。

然后在应用启动的时候加载进来.AntilazyLoad类所在的dex包必须被先加载进来,不然AntilazyLoad类会被标记为不存在

即使后续加载了hack.dex包那么他也是不存在的这样屏幕就会出现茫茫多的类AntilazyLoad找不到的log。

所以Application作为应用的入口不能插入这段代码。(因为载入hack.dex的代码是在Application中onCreate中执行的,

如果在Application的构造函数里面插入了这段代码,那么就是在hack.dex加载之前就使用该类,该类一次找不到,会被永远的打上找不到的标志)

其中:



0 0