JNI 函数调用上的 ClassCastException:CallVoidMethod
ClassCastException on JNI function call: CallVoidMethod
我正在尝试从 Android 应用程序中的本机 C++ 代码调用 java 方法。当我尝试调用我的 Java 方法时发生异常。我看过几个例子,但我无法弄清楚我做错了什么。请帮助我。
Java 边:
public class UsbAudioRecorder {
private UsbAudioRecordListener listener;
UsbAudioRecorder(UsbAudioRecordListener listener){
this.listener = listener;
}
static {
System.loadLibrary("usbaudio");
}
public native int native_setupConnection(final int fd, final String usbfs_path);
public native void start();
public void received(byte[] audio){
listener.recorded(audio);
}
//some more methods...
}
本机代码:
static jclass class_usbAudioRecorder = NULL;
static jmethodID methId_UsbAudioRecorder_received;
JNIEXPORT jint JNICALL Java_com_example_soundcard_UsbAudioRecorder_native_1setupConnection
(JNIEnv *env , jobject obj, jint fd, jstring usbfs_path){
// Get the objects class
jclass clazz = env->GetObjectClass(obj);
if (!clazz) {
LOGD("Could not find class");
error = LIBUSB_ERROR_OTHER;
}
class_usbAudioRecorder = (jclass) env->NewGlobalRef(clazz);
env->DeleteLocalRef(clazz);
// Get the callbacks method id
methId_UsbAudioRecorder_received = env->GetMethodID(class_usbAudioRecorder,"received", "([B)V");
if (!methId_UsbAudioRecorder_received) {
LOGD("Could not find method");
env->DeleteGlobalRef((jobject) class_usbAudioRecorder);
error = LIBUSB_ERROR_OTHER;
goto err;
}
// event handle callback
static void cb_trans(struct libusb_transfer* transfer){
// Create a jbyteArray.
jbyteArray audioArray = env->NewByteArray(PACKET_SIZE * transfer->num_iso_packets);
//here i populate jbyteArray with data
// Callback
env->CallVoidMethod(class_usbAudioRecorder, methId_UsbAudioRecorder_received, audioArray);
// cleaning up
env->DeleteLocalRef(audioArray);
jthrowable exc;
exc = env->ExceptionOccurred();
if (exc) {
env->ExceptionDescribe();
}
if (env->ExceptionCheck()) {
LOGD("Exception while trying to pass sound data to java");
env->ExceptionClear();
return;
}
异常输出:
10-27 15:19:55.658 11890-12476/com.example.soundcard W/System.err:
java.lang.ClassCastException: [B cannot be cast to
com.example.soundcard.UsbAudioRecorder 10-27 15:19:55.658
11890-12476/com.example.soundcard W/System.err: at
java.lang.Class.cast(Class.java:1278) 10-27 15:19:55.663
11890-12476/com.example.soundcard W/System.err: at
com.example.soundcard.UsbAudioRecorder.start(Native Method) 10-27
15:19:55.663 11890-12476/com.example.soundcard W/System.err: at
com.example.soundcard.MainActivity$OnClickListener.run(MainActivity.java:279)
10-27 15:19:55.663 11890-12476/com.example.soundcard W/System.err:
at java.lang.Thread.run(Thread.java:841)
我找到了解决办法。只是为了节省别人一些时间:
调用非静态方法时,您需要将 class 实例作为 jobject
传递给 CallVoidMethod
。我的错误是使用仅适用于静态方法的 jclass
来调用它。
我正在尝试从 Android 应用程序中的本机 C++ 代码调用 java 方法。当我尝试调用我的 Java 方法时发生异常。我看过几个例子,但我无法弄清楚我做错了什么。请帮助我。
Java 边:
public class UsbAudioRecorder {
private UsbAudioRecordListener listener;
UsbAudioRecorder(UsbAudioRecordListener listener){
this.listener = listener;
}
static {
System.loadLibrary("usbaudio");
}
public native int native_setupConnection(final int fd, final String usbfs_path);
public native void start();
public void received(byte[] audio){
listener.recorded(audio);
}
//some more methods...
}
本机代码:
static jclass class_usbAudioRecorder = NULL;
static jmethodID methId_UsbAudioRecorder_received;
JNIEXPORT jint JNICALL Java_com_example_soundcard_UsbAudioRecorder_native_1setupConnection
(JNIEnv *env , jobject obj, jint fd, jstring usbfs_path){
// Get the objects class
jclass clazz = env->GetObjectClass(obj);
if (!clazz) {
LOGD("Could not find class");
error = LIBUSB_ERROR_OTHER;
}
class_usbAudioRecorder = (jclass) env->NewGlobalRef(clazz);
env->DeleteLocalRef(clazz);
// Get the callbacks method id
methId_UsbAudioRecorder_received = env->GetMethodID(class_usbAudioRecorder,"received", "([B)V");
if (!methId_UsbAudioRecorder_received) {
LOGD("Could not find method");
env->DeleteGlobalRef((jobject) class_usbAudioRecorder);
error = LIBUSB_ERROR_OTHER;
goto err;
}
// event handle callback
static void cb_trans(struct libusb_transfer* transfer){
// Create a jbyteArray.
jbyteArray audioArray = env->NewByteArray(PACKET_SIZE * transfer->num_iso_packets);
//here i populate jbyteArray with data
// Callback
env->CallVoidMethod(class_usbAudioRecorder, methId_UsbAudioRecorder_received, audioArray);
// cleaning up
env->DeleteLocalRef(audioArray);
jthrowable exc;
exc = env->ExceptionOccurred();
if (exc) {
env->ExceptionDescribe();
}
if (env->ExceptionCheck()) {
LOGD("Exception while trying to pass sound data to java");
env->ExceptionClear();
return;
}
异常输出:
10-27 15:19:55.658 11890-12476/com.example.soundcard W/System.err: java.lang.ClassCastException: [B cannot be cast to com.example.soundcard.UsbAudioRecorder 10-27 15:19:55.658 11890-12476/com.example.soundcard W/System.err: at java.lang.Class.cast(Class.java:1278) 10-27 15:19:55.663 11890-12476/com.example.soundcard W/System.err: at com.example.soundcard.UsbAudioRecorder.start(Native Method) 10-27 15:19:55.663 11890-12476/com.example.soundcard W/System.err: at com.example.soundcard.MainActivity$OnClickListener.run(MainActivity.java:279) 10-27 15:19:55.663 11890-12476/com.example.soundcard W/System.err:
at java.lang.Thread.run(Thread.java:841)
我找到了解决办法。只是为了节省别人一些时间:
调用非静态方法时,您需要将 class 实例作为 jobject
传递给 CallVoidMethod
。我的错误是使用仅适用于静态方法的 jclass
来调用它。