注意事项

使用 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.arraycopymodelPaths的赋值失效,所以需要将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 *;
    }