Meituan-Dianping / Robust

Robust is an Android HotFix solution with high compatibility and high stability. Robust can fix bugs immediately without a reboot.
Apache License 2.0
4.42k stars 807 forks source link

Lambda 表达式不能正常插桩 #252

Open devLiuGit opened 6 years ago

devLiuGit commented 6 years ago

异常类型:编译异常

Robust版本:0.4.78

Gradle版本:2.14.1

系统 : Mac

堆栈/日志:

工程中使用 retroLambda, 同 RobustSample 工程 gradle 配置顺序, autoPatch 在 retroLambda 之后.

apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'
//apply plugin: 'auto-patch-plugin'
apply plugin: 'robust'

修复lambda 表达式 :

xxx.setOnClickListener(view -> {
    RobustModify.modify();
    //...
});

autoPatch 提示 patch method is empty ,please check your Modify annotation or use RobustModify.modify() to mark modified methods.

经过排查, 因为 methodsMap.robust 文件中未记录相关方法信息, 即相关方法未被插桩.

原始代码

textView.setOnClickListener(v -> {
    Log.d("robust", " onclick  in Listener");
});

编译后

textView.setOnClickListener(g.a());

retroLambda 生成 class Xxx $$ lambda, RobustSample 中已被混淆

public final /* synthetic */ class g implements OnClickListener {
    public static ChangeQuickRedirect a;
    private static final g b = new g();

    private g() {
    }

    public static OnClickListener a() {
        return b;
    }

    @Hidden
    public void onClick(View view) {
        if (PatchProxy.isSupport(new Object[]{view}, this, a, false, 7, new Class[]{View.class}, Void.TYPE)) {
            PatchProxy.accessDispatch(new Object[]{view}, this, a, false, 7, new Class[]{View.class}, Void.TYPE);
            return;
        }
        SecondActivity.b(view);
    }
}

编译后, lambda 表达式中逻辑

private static /* synthetic */ void b(View view) {
        if (PatchProxy.isSupport(new Object[]{view}, null, n, true, 20, new Class[]{View.class}, Void.TYPE)) {
            PatchProxy.accessDispatch(new Object[]{view}, null, n, true, 20, new Class[]{View.class}, Void.TYPE);
            return;
        }
        Log.d("robust", " onclick  in Listener");
    }

以上代码为 RobustSample 中对 Lambda 表达式修复后的反编译结果, 此时 Lambda 表达式可以正常修复. 但是在集成到实际项目中后, Lambda 表达式经 retroLambda 处理后的相关方法并没有正常插桩.

之后为了排除变量, 项目集成配置都参考 RobustSample 仍然出现同样的问题.

对比 RobustSample 与 集成项目的反编译结果, 区别仅在于 RobustSample retroLambda 生成类名已经被混淆, 而集成项目中名为 Xxx $$ lambda.

请问, 为什么集成到项目中后会出现 lambda 相关方法无法正常插桩, 而 RobustSample 却没有问题?

hedex commented 6 years ago

可以看看你的methodmap.robust文件吗?

devLiuGit commented 6 years ago

methodsMap.robust.zip @hedex