xposed 调用callMethod 碰到接口作为参数 如何传递对象

举例:XposedHelpers.callMethod 调用setListener函数 listener 接口如何作为参数传递。(实际中listener是hook对象app自定义、无法直接实现)
图片说明

第一种:写一个和app同样操作的Listener
第二种:如果app的Listener是this、成员变量直接反射传进去即可
如果只是方法的局部变量那么只能使用第一种了

hook方法

if (lpparam.packageName.equals("com.libok.androidnote")) {
    Log.e(TAG, "handleLoadPackage: Note");
    Class Builder = lpparam.classLoader.loadClass("com.libok.basic.util.DialogUtil$Builder");
    final Class negativeListener = lpparam.classLoader.loadClass("com.libok.basic.util.DialogUtil$OnNegativeClickListener");
    Log.e(TAG, "handleLoadPackage: " + Builder.getSimpleName() + " " + negativeListener.getSimpleName());
    XposedHelpers.findAndHookMethod(Builder, "setNegativeClickListener", negativeListener, new XC_MethodHook() {
        @Override
        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
            super.beforeHookedMethod(param);
            Log.e(TAG, "beforeHookedMethod: " + param.args.length + " " + param.args[0].getClass().toString());
            Class<?> listenerClass = param.args[0].getClass();
            Log.e(TAG, "beforeHookedMethod: " + listenerClass);
            Method[] declaredMethods = listenerClass.getDeclaredMethods();
            for (Method method : declaredMethods) {
                Log.e(TAG, "beforeHookedMethod: method " + method.getName());
            }
            MyHandler handler = new MyHandler();
            Object listener = Proxy.newProxyInstance(lpparam.classLoader, new Class[]{negativeListener}, handler);
            param.args[0] = listener;
        }
        @Override
        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
            super.afterHookedMethod(param);
        }
    });
}

MyHandler.java

class MyHandler implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("onNegativeTest")) {
            Log.e(TAG, "invoke: +++++hiahiahiahia onNegativeTest");
        } else if (method.getName().equals("onNegativeClick")) {
            Log.e(TAG, "invoke: -----hiahiahiahia onNegativeClick");
        }
        return null;
    }
}

DialogUtil就是一个Dialog工具类,setNegativeClickListener方法就是设置Dialog的取消按钮的自定义回调

OnNegativeClickListener.java

/**
 * 取消按钮回调
 */
public interface OnNegativeClickListener {
    void onNegativeClick();
    void onNegativeTest();

具体执行

if (mNegativeClickListener != null) {
    mNegativeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mNegativeClickListener.onNegativeClick();
            dialog.dismiss();
        }
    });
    mNegativeButton.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            mNegativeClickListener.onNegativeTest();
            return false;
        }
    });
}

在长按NegativeButton时会输出invoke: +++++hiahiahiahia onNegativeTest
短按会输出invoke: -----hiahiahiahia onNegativeClick

Listener拦截完毕