整体来说Robust热更新系统分为了四个模块,如下图:
-
autopatchbase
是整个项目的一个基础库,用于存放公共的代码 -
gradle-plugin
是Robust的插桩插件,会对指定的类插入静态字段ChangeQuickRedirect,对类的方法插入桩判定代码,是Robust的核心思想库 -
auto-patch-plugin
这个库是整个项目最复杂的一块,需要针对不同的代码风格、ReProguard补丁代码,生成一个可用的补丁。这部分的难点重点体现在Proguard对代码进行混淆之后,补丁中的代码也需要按照之前的Proguard规则来进行重新一次Proguard,我把这个过程称为ReProguard。这部分可以参考一下之前的博客:Android热更新方案Robust开源 -
patch
是补丁加载的核心,这部分控制了如何加载补丁,可以根据自己的需求定制化自己的补丁加载、校验等策略。
com.meituan.robust.patch.annotaion.Add
这是自动化补丁使用的注解,用来标记新增的类和方法,目前还不支持新增字段。
com.meituan.robust.patch.annotaion.Modify
这个注解用来标记被改动的方法或者类,如果这个注解是放在一个类A上面,自动化补丁会生成类APatch,APatch会被打入补丁,原始APK中的类A中每个方法都不会被执行,只会执行APatch中的方法,相当于把A类“替换为”APatch类(请注意这里只是和替换一个类有相同的效果,实际上A类依然在APK中,此时的A成为了一个傀儡,APatch才是幕后黑手);如果注解标记的是方法,则表明这个方法是需要被打入补丁中的,只有被标注的方法会打入补丁,打入补丁之后,就会执行补丁的方法,原始方法不会在执行。
com.meituan.robust.utils.EnhancedRobustUtils
反射的工具类。
com.meituan.robust.utils.PatchTemplate
补丁的模板类,补丁中的类会填充这个模板生成补丁的转发类(这部分可以参看补丁的结构)com.meituan.robust.ChangeQuickRedirect
这个接口在上面的代码结构中出现的频率比较高,我们在代码中插入的字段就是这个接口,同时这个接口也是上述xxcontrol
的实现接口,这个接口包含了两个方法:
public interface ChangeQuickRedirect {
Object accessDispatch(String methodName, Object[] paramArrayOfObject);
boolean isSupport(String methodName, Object[] paramArrayOfObject);
}
方法isSupport
是用来判断方法是否需要被替换,而accessDispatch
在自动化补丁中这是对补丁方法的转发。
何时加载补丁
补丁的加载我们推荐越靠前越好,这样对bug的可修复范围就大大的增加,建议在Application onCreate方法或更早的时机加载补丁。
对于使用multidex的项目,需要确保所有的dex都已经加载,再加载补丁,避免被补丁的类由于没有加载而导致补丁应用失败,所以需要在补丁加载之前保证所有dex都已经加载。