使用 InstantRun 热修复需注意以下事项:
内部类的构造方法是 private(private 会生成一个匿名的构造函数)时,需要在制作补丁过程中手动修改构造方法的访问域为 public;
不支持 Patch 中包含 Lambda 等语法,需要在 Patch 时更换写法;
对于返回值是 this 的方法,暂不能完美支持,比如 Builder 模式,但在制作补丁代码时,可以通过增加一个类来包装,如下的 B 类:
method a(){ return this; } method a(){ return new B().setThis(this).getThis(); }
不支持修改、增加字段,可以通过增加新类,把字段放到新类中的方式来实现增加字段的能力;
新增的类支持静态内部类和非内部类;
对于只有字段访问的函数无法直接修复,可通过调用处理间接修复;
不支持构造方法的修复;
不支持所有被 AspectJ 切面的函数;
被 Patch 的类中,如果静态块里有调用等待其他功能初始化的代码,比如直接或间接调用
LauncherApplicationAgent.getInstance()
等,可能会导致启动卡死;如果被 Patch 的代码中,包含类似
System.arraycopy
的调用,由于 InstantRun 本身对 Patch 函数内容的反射调用处理,会导致System.arraycopy
对modelPaths
的赋值失效,所以需要将java.lang.System
加入不反射的列表,保证流程正确;如果System.arraycopy
的访问权限不是 public,可能就直接不支持被 Patch 了;@com.alipay.instantrun.patch.annotaion.Modify private void handleInit() { ...... String[] modelPaths = new String[1 + mExtraModels.length]; modelPaths[0] = mModelPath; System.arraycopy(mExtraModels, 0, modelPaths, 1, mExtraModels.length); int[] modelTypes = new int[1 + mExtraModelTypes.length]; System.arraycopy(mExtraModelTypes, 0, modelTypes, 1, mExtraModelTypes.length); ...... }
如果是 Bundle 级别主动接入,注意 gradle 3.6 及以上版本默认启用 R8,会将插入的 Field 变量优化掉,需要在混淆文件
proguard-rules.pro
中加入以下代码:-keepclassmembers class **{ public static com.alipay.instantrun.ChangeQuickRedirect *; }
文档内容是否对您有帮助?