针对app线上修复技术,目前有好几种解决方案,开源界往往一个方案会有好几种实现。重复的实现会有造轮子之嫌,但分析解决方案在技术上的探索和衍变,这轮子还是值得去推动的 关于Hot Fix技术 Hot Fix技术,简单来说是针对线上已发布app出现了bug,在不推送新版本的情况下通过发布修复补丁进行修复。通常是刚上线的app,需要快速线上修复bug,类似的技术叫做热修复或热补丁。 热修复技术能带来什么? · 让app具有了上线后被修复的可能性,增加事故风险可控性; · 避免为修复bug而快速增发新版本,让用户“无感”,提升体验; · 推送新版本app修复时,用户升级覆盖面无法保证; · 避免增发修复版本的复杂流程,减少发布新版本app成本; 现有的技术方案 目前,从技术解决方案上来说,有以下几种思路: · Dexposed 来自阿里手淘团队,白衣(花名)基于Xposed实现了Dexposed,在此基础上手淘团队推出了HotPatch二方库。 · AndFix 出自阿里支付宝技术团队,同样是对方法的hook,但未基于Dexposed去实现,避免了在art上运行时存在兼容性问题。 · 基于ClassLoader QQ空间终端开发团队提供了技术思路,目前基于此实现的热门的开源项目有Nuwa,HotFix,DroidFix,这三种方案的原理却徊然不同,各有优缺点。 关于三者技术的介绍,这里推荐一篇文章:各大热补丁方案分析和比较,这里不做细说。 技术预研 热修复 == 动态替换 == 动态加载 得出上面的等式,是因为热修复一般来说是增发patch文件,避免用户调用错误代码,并不是直接修改了原来的代码。这相当于是对问题文件做了动态替换,而要实现动态替换是避免默认的加载,改变成动态地加载替换文件。 动态加载的基础是ClassLoader,Java程序在运行时加载对应的类是通过ClassLoader来实现的, Java 类可以被动态加载到 Java 虚拟机中并执行。所以ClassLoader所做的工作实质是把类文件从硬盘读取到内存中。
AndFix示例图
Java中ClassLoader的基本概念:
· 类加载器的树状结构:在JVM中,所有类加载器实例按树状结构组织,根结点为引导类加载器。除根结点外的所有类加载器都有一个非空的父类加载器,从而构成树状结构; · 双亲委托(代理)模型:当类加载器收到加载类或资源的请求时,通常都是先委托给父类加载器加载,也是说只有当父类加载器找不到指定类或资源时,自身才会执行实际的类加载过程; 代理模式是为了保证 Java 核心库的类型安全。通过代理模式,对于 Java 核心库的类的加载工作由bootClassLoader来统一完成,保证了 Java 应用所使用的都是同一个版本的 Java 核心库的类,是互相兼容的。 · 类的判等:即使类完全相同(名称相同、字节码相同),不同类加载器实例加载的类对象也是不相等的; 这条规则是Java类加载机制中非常核心的规则,它保证了类加载机制实现“类隔离”、“保护JDK中的基础类”等目标。 · 类的垃圾回收:只有当类加载器可被作为垃圾回收的前提下,其加载的类才有可能被回收; 源码分析ClassLoader机制