正文
热修复是什么?
刘昭认为,热修复是在应用的App包发布到市场之后,出现了Bug,无需替换包来进行在线更新的一种技术,对用户是无感知的。
泽胤认为,谈到热修复,就应该和动态部署的概念进行区分。热修复是特指对微小改动进行修复的一个技术,它强调快速和无感的修复。而动态部署会复杂更多,它涵盖的东西也更多,但核心的技术还是热修复技术。
步川认为,热修复可以从技术上来理解并和动态部署进行区分。他提到,目前广义上有两种方案可以实现代码的替换,一种是类的替换,基于Classloader,另一种是方法的替换,而这两种方式各有优缺点。
方法的替换:
只能替换方法的内容,所以不能够对要patch的类进行方法的新增和删除;但同时,方法的替换可以在应用不重启的情况下实现。它包小、快速、功能单一、比较轻量,这种方案是热修复。
类的替换:
可以修改类结构,功能更加的强大;但是必须要重启一次才会有效,因为已经加载过的类是不能够被替换的。这种方案叫做“动态部署”。它几乎能够适应任何代码的变更,所以很适合进行业务功能的迭代。
目前,业内有很多的热修复方案,步川就热修复技术向观众进行了对比讲解。他提到,从广义上来讲,热修复的实现方式可以被分为类的替换和方法的替换。
类的替换
如图1所示,APK包中包含了代码和资源,代码存放在classes.dex中,资源存放在APK的res目录下,系统会通过ClassLoader装载classes.dex来进行类加载。如果有多个classes.dex,那么这多个classes.dex会在ClassLoader中会用数组的形式来进行组织,然后从前往后进行遍历查找。
图1
一种具体的方案如图2所示,是
利用多dex从前往后遍历的有序特性,把patch.dex插入到数组的最前面,对patch进行有限查找,达到替换的目的
,这时候就会出现preverify问题,为了绕过这个问题,就必须往每个类的构造函数里面进行插桩防止安装期间的校验,把校验从编译期间移动到了运行期间,导致运行期间每加载一个类,都要进行校验和优化,降低了运行性能。