热更新简述
热更新 主要是差量更新,避免在apk功能升级之后 需要重新下载整个的apk,避免用户流量损耗。而热更新 主要分为两派 微信thinker系列 和 阿里andFix系列
微信的thinker
微信Tinker为了解决QQ空间补丁技术由于插桩带来的效率问题,引入DEX差量包。其主要的原理与QQ空间超级补丁技术基本相同,最大区别在于:不再将Patch.dex增加到Elements数组中,而是差量的方式给出Patch.Dex;然后将Patch.Dex与应用的Classes.Dex合并,然后整体替换掉旧的DEX,达到修复的目的。
该方案中通过自研DexDiff算法,深度利用Dex格式来减少差异的大小,从而做到补丁包足够小。其缺点在于:不支持实时生效;由于补丁DEX需要和原DEX合并,需要占用额外内存和磁盘空间,并且很容易因为内存消耗等原因合并失败;与QQ空间补丁技术相同,同样需要侵入式打包。
阿里的AndFix
阿里andfix 热修复方案通过Hook本地方法. 并没有整体替换class,整体流程如下:第一步,打开链接库得到操作句柄, 获取native层内部函数, 得到classobject对象;第二步,修复访问权限属性为Public ;第三步,得到新旧方法的指针,新方法指向目标方法,实现方法的替换。
整个过程中不侵入打包,性能无损耗;同时可以即时生效。其缺点同样明显:兼容性方面很不稳定,需要针对Dalvik虚拟机和Art虚拟机做适配;不支持 类方法/字段,以及修改 方法,也不支持 对;运行时方法被Patch,有Crash风险
阿里Hotfix 1.x版本
阿里Hotfix 1.x在AndFix的基础上,增加了补丁管理后台;同时基于手淘的实践,针对AndFix做了大量优化, 性能上提高了兼容和稳定性;功能上支持 新增类并提供了更小的补丁包(这是因为基于类方法作为粒度)
1.缺点:
1.1不支持资源、So文件修复;不支持新增类方法/类字段,这是因为Hotfix 1.x本质上是Hook一个已存在的的方法;
1.2 参数包括Long、Double、Float基本类型的方法不能被Patch,同时参数超过8的方法不能被Patch;
1.3被反射调用的方法不能被Patch,具体来说是非静态方法的反射调用会提示IllegalArgumentException 异常,当静态方法被反射调用,
如果反射调用不涉及类对象,则可以被Patch;
1.4构造方法不能被Patch,实际上不允许修改一个类字段(包括静态的和非静态的)
1.5正在运行的方法不能被Patch,也就是说如果一个方法正在运行,然后方法的在Native层的结构被替换, 那么就很可能导致Crash。
综上所述
阿里Hotfix和主流的热修复方案的效果对比。可以看出,在即时生效、性能消耗、Rom体积、接入复杂度、补丁包大小、类替换、SO文件替换、资源方案等方面,百川Hotfix都具有相对的优势。
自己实践bsdiff
bsdiff 并 不是专门为 apk增量更新设计的,它可以对任何二进制文件进行差分 和 合并 。bzip2的功能是利用哈夫曼编码 对文件进行无损压缩 (将差分包 进行压缩便于网络传输 )和解压。所以完整的流程是这样的:
1:bsdiff生成 patch-> bzip2压缩-> android下载patch-> bzip2解压patch-> bspatch合并patch-> 新的apk
主要能够实现:
1:修复方法级别的bug
2:新增类文件,资源布局等
3:保证基础更新的apk 与差量生成patch文件的 基础apk一一致,否则会报 解析包异常 的问题