JNI函数调用的ClassCastException:CallVoidMethod

时间:2015-10-27 15:09:13

标签: java android c++ java-native-interface

我试图从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无法强制转换为   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 $ 1.run(MainActivity.java:279)   10-27 15:19:55.663 11890-12476 / com.example.soundcard W / System.err:
  在java.lang.Thread.run(Thread.java:841)

1 个答案:

答案 0 :(得分:1)

我找到了解决方案。只是为了节省一些时间: 调用非静态方法时,需要将类实例作为CallVoidMethod传递给jobject。我的错误是用jclass来调用它,它只适用于静态方法。