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

Modify 方法嵌套 Add 方法,导致反射调用 Add 方法失败 #261

Open w4lle opened 6 years ago

w4lle commented 6 years ago

异常类型:app运行时异常,反射Add方法调用失败

手机型号:OnePlus3

手机系统版本:如:Android 8.0

Robust版本:0.4.78

Gradle版本:3.3

系统:Mac

堆栈/日志:

04-11 10:13:34.965 11645-11645/com.zhangdan.app W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference
04-11 10:13:34.968 11645-11645/com.zhangdan.app W/System.err:     at com.meituan.robust.utils.EnhancedRobustUtils.invokeReflectMethod(EnhancedRobustUtils.java:34)
04-11 10:13:34.969 11645-11645/com.zhangdan.app W/System.err:     at com.meituan.robust.patch.MeFragmentPatch.initView(MeFragmentPatch.java:115)
04-11 10:13:34.971 11645-11645/com.zhangdan.app W/System.err:     at com.meituan.robust.patch.MeFragmentPatch.RobustPublicinitView(Unknown Source:0)
04-11 10:13:34.972 11645-11645/com.zhangdan.app W/System.err:     at com.meituan.robust.patch.MeFragmentPatchControl.accessDispatch(Unknown Source:141)
04-11 10:13:34.974 11645-11645/com.zhangdan.app W/System.err:     at com.meituan.robust.PatchProxy.accessDispatch(PatchProxy.java:94)
04-11 10:13:34.975 11645-11645/com.zhangdan.app W/System.err:     at com.meituan.robust.PatchProxy.proxy(PatchProxy.java:44)
04-11 10:13:34.977 11645-11645/com.zhangdan.app W/System.err:     at com.zhangdan.app.me.ui.MeFragment.initView(Unknown Source:12)
04-11 10:13:34.978 11645-11645/com.zhangdan.app W/System.err:     at com.zhangdan.app.me.ui.MeFragment.onViewCreated(MeFragment.java:101)

修改方法如下:

    @Modify
    private void initView() {
        Log.d("MeFragment initView", "MeFragment 修复非static方法");
        initRefreshView();
        initConfigItemsView();
        initHeadView();
        Log.d(AddFixCls.getInstance().getRobustTag(), getFixString());
    }

    @Add
    private String getFixString() {
        return "在类中新增非static方法";
    }

其中 AddFixCls 是新增类,调用是没问题的,可以正常调用到,最终问题出在调用 getFixString() 方法上。 反编译patch如下:

patch.class
    private void initView() {
        ...
        obj = (AddFixCls) EnhancedRobustUtils.invokeReflectStaticMethod("getInstance", AddFixCls.class, getRealParameter(new Object[0]), null);
        if (obj == this) {
            obj = ((MeFragmentPatch) obj).originClass;
        }
        String str = (String) EnhancedRobustUtils.invokeReflectMethod("getRobustTag", obj, new Object[0], null, AddFixCls.class);
        Log.d("robust", "invoke  method is       No:  162 getRobustTag");
        if (this == this) {
            obj2 = this.originClass;
        } else {
            MeFragmentPatch meFragmentPatch2 = this;
        }
//问题出在这里,obj2 实际上应该是 patch 类,但是被转成了originClass,去调用新增的 add 方法当然是调用不到的。
        String str2 = (String) EnhancedRobustUtils.invokeReflectMethod("getFixString", obj2, new Object[0], null, MeFragment.class);
        Log.d("robust", "invoke  method is       No:  163 getFixString");
        ((Integer) EnhancedRobustUtils.invokeReflectStaticMethod("d", Log.class, getRealParameter(new Object[]{str, str2}), new Class[]{String.class, String.class})).intValue();
    }

    private String getFixString() {
        return "在类中新增非static方法";
    }

问题出在这里,obj2 实际上应该是 patch 类,但是被转成了originClass,去调用新增的 add 方法当然是调用不到的。

w4lle commented 6 years ago

同样的,对于类中新增static方法,结果是一样的。

        str = (String) EnhancedRobustUtils.invokeReflectStaticMethod("getStringIn", MainFragmentActivity.class, getRealParameter(new Object[0]), null);

应该是

        str = (String) EnhancedRobustUtils.invokeReflectStaticMethod("getStringIn", MainFragmentActivityPatch.class, getRealParameter(new Object[0]), null);

才可以运行正确

hedex commented 6 years ago

@w4lle 我们看看哈

xyzle commented 6 years ago

0.4.82也存在这个问题,这个bug啥时候改.

smallfour6 commented 5 years ago

发现同样的问题 0.4.82

jinyindao commented 5 years ago

这个问题我现在也遇到了,该怎么解决呢? 遇到的版本号是 0.4.87

jinyindao commented 5 years ago

@w4lle 你这边解决了这个问题了吗?目前我用的 robust 版本0.4.87

zd9453 commented 4 years ago

0.4.91 这个问题还是存在,已经不维护了吗?

EricZHD commented 4 years ago

0.4.99也这样。。 不能新增方法,那这个框架有什么用呢。。。 反射的时候调用的是orginClass对象 应该是代理对象才对 。。。 请问这个还有救吗

lifs419 commented 4 years ago

同问