java - 如何在 Android 中通过反射实例化一个监听器

标签 java android

我必须为 Android 1.6 (API 4) 开发一个应用程序,它应该能够在 Android 2.2 或更高版本的手机中使用 OnAudioFocusChangeListener(自 Android 2.2 - API 8 起可用)。

谁能告诉我如何通过反射实例化一个监听器? 我已经设法通过反射运行静态和非静态方法,但我不知道如何处理监听器。

这是监听器要反射(reflect)的:

AudioManager  audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

OnAudioFocusChangeListener audioListener = new OnAudioFocusChangeListener() {
    @Override
    public void onAudioFocusChange(int focusChange) {
    // code to execute
    }
};

public void getAudioFocus() {
    audioManager.requestAudioFocus(audioListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}

public void releaseAudioFocus() {
    audioManager.abandonAudioFocus(audioListener);
}

这是一个代码示例,其中包含我设法通过反射运行的方法:

Class BluetoothAdapter = Class.forName("android.bluetooth.BluetoothAdapter");
Method methodGetDefaultAdapter = BluetoothAdapter.getMethod("getDefaultAdapter"); // static method from the BluetoothAdapter class returning a BluetoothAdapter object
Object bluetooth = methodGetDefaultAdapter.invoke(null);
Method methodGetState = bluetooth.getClass().getMethod("getState"); // non-static method executed from the BluetoothAdapter object (which I called "bluetooth") returning an int
int bluetoothState = (Integer) methodGetState.invoke(bluetooth);

最佳答案

最后我使用代理类解决了它。这是代码!

private AudioManager theAudioManager;
private Object myOnAudioFocusChangeListener = null;

private static final int AUDIOMANAGER_AUDIOFOCUS_GAIN = 1;
private static final int AUDIOMANAGER_AUDIOFOCUS_LOSS = -1;

theAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

// instantiating the OnAudioFocusChangeListener by reflection (as it only exists from Android 2.2 onwards)
// we use a Proxy class for implementing the listener
public void setOnAudioFocusChangeListener() {
    Log.i(this, "setOnAudioFocusChangeListener()");
    Class<?>[] innerClasses = theAudioManager.getClass().getDeclaredClasses();
    for (Class<?> interfaze : innerClasses) {
        if (interfaze.getSimpleName().equalsIgnoreCase("OnAudioFocusChangeListener")) {
            Class<?>[] classArray = new Class<?>[1];
            classArray[0] = interfaze;
            myOnAudioFocusChangeListener = Proxy.newProxyInstance(interfaze.getClassLoader(), classArray, new ProxyOnAudioFocusChangeListener());
        }
    }
}

// called by onResume
public void getAudioFocus() {
    if (myOnAudioFocusChangeListener != null) {
        Log.i(this, "getAudioFocus()");
        try {
            Method[] methods = theAudioManager.getClass().getDeclaredMethods();
            for (Method method : methods) {
                if (method.getName().equalsIgnoreCase("requestAudioFocus")) {
                    method.invoke(theAudioManager, myOnAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AUDIOMANAGER_AUDIOFOCUS_GAIN);
                    Log.i(this, "requestAudioFocus");
                }
            }
        } catch (Exception e) {
            Log.e(this, e.getMessage());
        }
    }
}

// called by onPause
public void releaseAudioFocus() {
    if (myOnAudioFocusChangeListener != null) {
        Log.i(this, "releaseAudioFocus()");
        try {
            Method[] methods = theAudioManager.getClass().getDeclaredMethods();
            for (Method method : methods) {
                if (method.getName().equalsIgnoreCase("abandonAudioFocus"))
                    method.invoke(theAudioManager, myOnAudioFocusChangeListener);
            }
        } catch (Exception e) {
            Log.e(this, e.getMessage());
        }
    }
}

PROXY OnAudioFocusChangeListener 类

private class ProxyOnAudioFocusChangeListener implements InvocationHandler {

    // implements the method onAudioFocusChange from the OnAudioFocusChangeListener
    public void onAudioFocusChange(int focusChange) {
        Log.e(this, "onAudioFocusChange() focusChange = " + focusChange);
        if (focusChange == AUDIOMANAGER_AUDIOFOCUS_LOSS) {
            Log.i(this, "AUDIOMANAGER_AUDIOFOCUS_LOSS");
            Message msg = mHandler.obtainMessage(ControllerHandler.SET_ON_PAUSE);
            mHandler.sendMessage(msg);
        } else if (focusChange == AUDIOMANAGER_AUDIOFOCUS_GAIN) {
            Log.i(this, "AUDIOMANAGER_AUDIOFOCUS_GAIN");
            // no action is taken
        }
    }

    // implements the method invoke from the InvocationHandler interface
    // it intercepts the calls to the listener methods
    // in this case it redirects the onAudioFocusChange listener method to the OnAudioFocusChange proxy method
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        try {
            if (args != null) {
                if (method.getName().equals("onAudioFocusChange") && args[0] instanceof Integer) {
                    onAudioFocusChange((Integer) args[0]);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
        }
        return result;
    }   
}

关于java - 如何在 Android 中通过反射实例化一个监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7504556/

相关文章:

java - 如何在@RequestParam中传递符号&?

java - 在 SQLite 中使用 Blob 字段作为查询参数

android - retrofit - 删除为空但响应主体类型被声明为非空

java - 正确的 HTTP 客户端方法

android - 如何从屏幕确定在 3D 空间中触摸了什么?

java - Java 中的多重分割

java - 在 Java 中实现 friend (在 C++ 中可用)功能

java - 如何在 Activity 中显示购物车图标?

android - 推送通知以获取设备位置

java - 通过 BLE 将 GZIP 数据从 Android 发送到 NodeJS