android-hotfix(QQ空间思路)浅析

hotfix,最直观的理解就是我们用的windows系统了。
windows系统会不定期下发一些补丁,我们安装这些补丁,系统的BUG也就被修复了。
所以说,hotfix是一种有效修复BUG的方式。
 
app产品不同于web产品,app硬伤之一便是不能及时修正BUG,制作修复包->用户下载新包->安装,这个流程不仅复杂,而且也不能保证线上版本就是修复版,BUG还是会一直存在的。
如果在android端能够实现hotfix,那么BUG修复就不会那么复杂了,同时也能够收敛app版本。
 
最近学习了QQ空间的热修复思路,同时也研究了一下github上基于此种思路的实现方案,接下来总结一下这种方案吧
 
实践基础:
1.QQ空间的热修补思路     http://bugly.qq.com/blog/?p=781    (必读哦)
2.github开源项目
  dodola/HotFix     https://github.com/dodola/HotFix    (百度同学实现)
  jasonross/Nuwa  https://github.com/jasonross/Nuwa (点评同学实现)
 
适用范围:
已经测试了4.0至6.0的系统版本,均能实现热修补。
 
dodola的实现方案非常简单,作为demo非常好,能够理解整个hotfix流程。
nuwa的实现更完善一些,可供大家直接使用。
 
接下来串一下思路,对hotfix有一个印象:
1.针对线上apk中的BUG,我们可以考虑通过hotFix用fixed类替换bug类,替换后即可正常运行。
  **需要对bug类进行修复,修正为fixed类,再考虑用fixed类替换bug类。
2.要用fixed.class替换bug.class,就需要classLoader加载的是fixed.class而不是bug.class
  **通过动态修改classLoader里的pathList,将fixed.class放置到bug.class前面,classLoader加载到fixed.class就不会再继续寻找bug.class了。
3.apk在安装阶段进行dex->odex时会判断class直接引用是否都在当前dex内,若是则打上CLASS_ISPREVERIFIED标记。若被打上此标记,则class只会在当前dex中查找直接引用的class,不能达到替换的效果。
  **要对替换类的引用类进行清除CLASS_ISPREVERIFIED标记操作,做法是打包阶段class中动态插入其他dex中的class,可以借助javassist。
 
自此,我们清楚了,进行hotfix需要解决两个问题:
1.尽量把所有的类都去掉CLASS_ISPREVERIFIED标记,这样才能随心所欲的进行class替换(性能什么的,是可以优化的,BUG可是要崩溃的)。所以我们要制作一个inject_dex,动态注入到尽量多的类里。
2.我们要打包fixed_dex,将需要替换的class放到里边。
 
那么接下来从代码的流程上看一下怎么来实现:
1.A工程中写一个BugClass.java,里边有一个方法,return “bug”。
2.B工程中写一个类AntilazyLoad.java,不含有任何内容,就是用来让A工程引用外部class的。
3.A工程中写一个HotFix.java,里边包含合并dex的代码,并且将其他dex放到A.dex前面。
4.A工程中的Application中调用HotFix进行合并dex,保证A.dex在其他dex之后。
5.A工程在打包阶段通过javassist进行动态注入,将AnitilazyLoad.class注入到需要替换的类构造器中。(这一步清除了CLASS_ISPREVERIFIED)。
6.对AntilazyLoad和修正后的BugClass分别打包,inject_dex和fixed_dex。
7.放入到assets中,供Application初始化的时候进行处理。fixed_dex一般都是放在云端的,但是从云端和assets中获取,实际上没啥差别,demo就用assets就可以了。
运行,在Application中合并dex后,实际上已经修复了BUG。
 
还有dexposed和andFix以及其他方案,待后续学习。 
  
原文地址:https://www.cnblogs.com/puff/p/5038616.html