|
| 1 | + |
| 2 | +热修复实现(一) |
| 3 | +=== |
| 4 | + |
| 5 | +之前也分析过`InstantRun`的源码,前面也写了一篇热修复实现原理的文章。 |
| 6 | + |
| 7 | +But,最近遇到困难了,所在项目要做插件化,同事在开发过程中遇到了一个在5.0以下手机崩溃的问题,想着一起找找原因修复下。 |
| 8 | +但是这个bug已经折腾了我两天了,只找到原因,并没有找出任何解决方案。 |
| 9 | + |
| 10 | +深深的感觉到之前的那些都是皮毛,没有真正的去做,真正的去处理一些细节,那些都是没任何意义的。 |
| 11 | + |
| 12 | +所以这里系统学习一下,既然学习,就找一个做的最好的来学。 |
| 13 | + |
| 14 | + |
| 15 | +前面的文章也介绍了,目前存在的几个开源框架: |
| 16 | + |
| 17 | +- 手机淘宝基于Xposed进行了改进,产生了针对Android Dalvik虚拟机运行时的Java Method Hook技术-Dexposed。 |
| 18 | +但这个方案犹豫底层Dalvik结构过于依赖,最终无法兼容Android 5.0以后的ART虚拟机。 |
| 19 | + |
| 20 | +- 支付宝提出了新的方案Andfix,它同样是一种底层结构替换的方案,也达到了运行时生效即时修复的效果,而且做到了Dalvik和ART全版本的兼容。然而它也 |
| 21 | +是由局限性的,且不说其底层固定结构的替换方案稳定性不好,其使用范文也存在着诸多限制,虽然可以通过代码改造来绕过限制达到同样的 |
| 22 | +修复目的,但是这种方式即不优雅也不方便。而且更大的问题是Andfix只提供了代码层面的修复,对于资源和so的修复都还未实现。 |
| 23 | + |
| 24 | +- 其他的就是微信Tinker、饿了么的Amigo、美团的Robust,不过他们都各自有各自的局限性,或者不够稳定、或者补丁过大、或者效率低下 |
| 25 | +,或者使用起来太繁琐,大部分技术上看起来似乎可行,但是实际体验并不好。 |
| 26 | + |
| 27 | +我们学习的就是阿里巴巴的新一代非侵入式Android热修复方案-Sophix。 |
| 28 | +它各个方面都比较优秀,使用也比较方便,唯一不支持的就是四大组件的修复。这是因为如果修复四大组件,必须在AndroidManifest里面预先插入代码组件,并且尽可能声明所有权限,这样就会给 |
| 29 | +原先的app添加很多臃肿的代码,对app运行流程的侵入性很强。 |
| 30 | + |
| 31 | + |
| 32 | +在Sophix中,唯一需要的就是初始化和请求补丁两行代码,甚至连入口Application类我们都不需要做任何修改。 |
| 33 | + |
| 34 | +这样就给了开发者最大的透明度和自由度。我们甚至重新开发了打包工具,使的补丁工具操作图形界面化,这种所见即所得的补丁生成 |
| 35 | +方式也是阿里热修复独家的,因此,Sophix的接入成本也是目前市面上所有方案里最低的。 |
| 36 | + |
| 37 | + |
| 38 | + |
| 39 | + |
| 40 | +代码修复 |
| 41 | +--- |
| 42 | + |
| 43 | +代码修复有两大主要方案: |
| 44 | + |
| 45 | +- 阿里系的底层替换方案:底层替换方案限制颇多,但是时效性最好,加载轻快,立即见效。 |
| 46 | + |
| 47 | + 底层替换方案是在已经加载了的类中直接替换掉原有的方法,是在原来类的基础上进行修改的。因而无法实现对原有类进行方法和字段的增减,因为这样将破坏原有类的结构。 |
| 48 | + 一旦补丁类中出现了方法的增加和减少,就会导致这个类以及整个dex的方法数的变化,方法数的变化伴随着方法索引的变化,这样在 |
| 49 | + 访问方法时就无法正常的索引到正确的方法了。如果字段发生了增加或减少,和方法变化的情况一样,所有字段的索引都会发生变化。 |
| 50 | + 而新方法中使用到这些老的示例对象时,访问新增字段就会会产生不可预期的结果。 |
| 51 | + |
| 52 | + 这是该类方案的固有限制,而底层替换方案最为人逅病的地方,在于底层替换的不稳定性。因为Hook方案,都是直接依赖修改虚拟机方法实体的具体字段。因为Art虚拟机和Dalvik虚拟机的不同,每个版本的虚拟机都要适配,而且Android系统是开源的,各个厂商都可以对代码进行改造,如果某个厂商进行了修改,那么这种通用性的替换机制就会出问题。这便是不稳定的根源。 |
| 53 | + |
| 54 | + |
| 55 | + |
| 56 | +- 腾讯系的类加载方案:类加载方案时效性差,需要重新冷启动才能见效,但修复范围广、限制少。 |
| 57 | + |
| 58 | +类加载方案的原理是在app重新启动后让classloader去加载新的类。因为在app运行到一半的时候,所有需要发生变更的类已经被加载过了,在Android上是无法对一个类进行卸载的。如果不重启,原来的类还在虚拟机中,就无法加载新类,因此只有在下次重启的时候, |
| 59 | +在还没走到业务逻辑之前抢先加载补丁中的新类,这样后续访问这个类的时候,就会用新类,从而达到热修复的目的。 |
| 60 | + |
| 61 | + |
| 62 | +为什么sophix更好? |
| 63 | +--- |
| 64 | + |
| 65 | +既然底层替换方案和类加载方案各有优点,把他们联合起来就是最好的选择。Sophix就是同时涵盖了这两种方案,可以实现优势互补、完全兼顾的作用,可以灵活的根据实际情况自动切换。 |
| 66 | + |
| 67 | + |
| 68 | + |
| 69 | + |
| 70 | + |
| 71 | + |
| 72 | +但是[Sophix](https://help.aliyun.com/document_detail/57064.html?spm=a2c4g.11186623.6.543.SPhMhO)有一个缺点就是,他不是开源的,而且是收费的。但是确实强大。 |
| 73 | + |
| 74 | + |
| 75 | + |
| 76 | + |
| 77 | +- [Google Instant app](https://developer.android.com/topic/instant-apps/index.html) |
| 78 | +- [微信热补丁实现](https://github.com/WeMobileDev/article/blob/master/%E5%BE%AE%E4%BF%A1Android%E7%83%AD%E8%A1%A5%E4%B8%81%E5%AE%9E%E8%B7%B5%E6%BC%94%E8%BF%9B%E4%B9%8B%E8%B7%AF.md#rd) |
| 79 | +- [多dex分拆](http://my.oschina.net/853294317/blog/308583) |
| 80 | +- [QQ空间热修复方案](https://mp.weixin.qq.com/s?__biz=MzI1MTA1MzM2Nw==&mid=400118620&idx=1&sn=b4fdd5055731290eef12ad0d17f39d4a) |
| 81 | +- [Android dex分包方案](http://my.oschina.net/853294317/blog/308583) |
| 82 | +- [类加载器DexClassLoader](http://www.maplejaw.com/2016/05/24/Android%E6%8F%92%E4%BB%B6%E5%8C%96%E6%8E%A2%E7%B4%A2%EF%BC%88%E4%B8%80%EF%BC%89%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%99%A8DexClassLoader/) |
| 83 | +- [基于cydia Hook在线热修复补丁方案](http://blog.csdn.net/xwl198937/article/details/49801975) |
| 84 | +- [Android 热补丁动态修复框架小结](http://blog.csdn.net/lmj623565791/article/details/49883661) |
| 85 | +- [美团Android DEX自动拆包及动态加载简介](http://tech.meituan.com/mt-android-auto-split-dex.html) |
| 86 | +- [插件化从放弃到捡起](http://kymjs.com/column/plugin.html) |
| 87 | +- [无需Root也能使用Xposed!](http://weishu.me/) |
| 88 | +- [当你准备开发一个热修复框架的时候,你需要了解的一切](http://www.zjutkz.net/2016/05/23/%E5%BD%93%E4%BD%A0%E5%87%86%E5%A4%87%E5%BC%80%E5%8F%91%E4%B8%80%E4%B8%AA%E7%83%AD%E4%BF%AE%E5%A4%8D%E6%A1%86%E6%9E%B6%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E4%BD%A0%E9%9C%80%E8%A6%81%E4%BA%86%E8%A7%A3%E7%9A%84%E4%B8%80%E5%88%87/) |
| 89 | + |
| 90 | + |
| 91 | +[1]: https://github.com/CharonChui/AndroidNote/blob/master/SourceAnalysis/InstantRun%E8%AF%A6%E8%A7%A3.md "InstantRun详解" |
| 92 | + |
| 93 | + |
| 94 | +--- |
| 95 | + |
| 96 | +- 邮箱 :charon.chui@gmail.com |
| 97 | +- Good Luck! |
0 commit comments