首页 > 解决方案 > 如何用反射实现接口并将其传递给Java中用反射调用的方法?

问题描述

我需要实现一个侦听器并将其传递给服务。我无法直接访问接口和服务类。

我被困在通过反射将代理接口传递给方法。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args) {

        try {
            Class<?> c = Class.forName("android.view.WindowManagerGlobal");
            Method m = c.getMethod("getWindowManagerService");
            Object windowManager = m.invoke(c.newInstance(), new Object[] {});

            Class<?> someInterface = Class.forName("android.view.WindowManagerService$WindowChangeListener");

            Object instance = createListenerInstance(someInterface);
            instance.getClass().getDeclaredMethod("windowsChanged", (Class<?>[]) null).invoke(instance, new Object[] {});
            System.out.println(instance.getClass().getName());

            // Fails with:
            // java.lang.NoSuchMethodException: android.view.WindowManagerService.addWindowChangeListener(com.sun.proxy.$Proxy0)
            windowManager.getClass().getMethod("addWindowChangeListener", instance.getClass()).invoke(windowManager, new Object[] { instance });

            System.out.println(windowManager.getClass().getName());
        } catch (Exception e) {
            System.out.println(e.getCause());
        }
    }

    private static Object createListenerInstance(Class<?> someInterface) {
        return Proxy.newProxyInstance(someInterface.getClassLoader(), new Class<?>[] { someInterface }, new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                // Handle the invocations
                if (method.getName().equals("windowsChanged")) {
                    System.out.println("windowsChanged");
                } else if (method.getName().equals("focusChanged")) {
                    System.out.println("focusChanged");
                }
                return args;
            }
        });
    }
}

以下是我无法通过 new 运算符或 ClassName.class 访问的一段代码:

package android.view;

public class WindowManagerService {

    public interface WindowChangeListener {
        public void windowsChanged();
        public void focusChanged();
    }
    public void addWindowChangeListener(WindowChangeListener listener) {
        System.out.println("Listener added: " + listener);
    }
    public void removeWindowChangeListener(WindowChangeListener listener) {
        System.out.println("Listener removed: " + listener);
    }
}

/////////
package android.view;

public class WindowManagerGlobal {
    private WindowManagerService windowManagerService = new WindowManagerService();

    public WindowManagerService getWindowManagerService() {
        return windowManagerService;
    }

    public void setWindowManagerService(WindowManagerService windowManagerService) {
        this.windowManagerService = windowManagerService;
    }
}

我不知道如何将代理对象传递给需要 WindowChangeListener 的方法。

标签: javareflectioninterface

解决方案


推荐阅读