Android NDK:从JNI C类调用java方法

时间:2013-03-08 11:01:42

标签: android android-ndk

我有JNI方法,我试图调用Java方法。这是我的JNI代码

void DummySink::afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes,
                  struct timeval presentationTime, unsigned /*durationInMicroseconds*/) {

     __android_log_print(ANDROID_LOG_VERBOSE, "RTSP", "Frame: %c", propRec->sPropBytes);
     jmethodID mid;
     jclass handlerClass = env9->FindClass("ob/android/Stream");
     if (handlerClass == NULL) {
         __android_log_print(ANDROID_LOG_VERBOSE, "RTSP-Error", "Class");
     }
     mid = env9->GetMethodID(handlerClass, "onResponse", "([B)V");
     if (mid == NULL) {
         __android_log_print(ANDROID_LOG_VERBOSE, "RTSP-Error", "Method");
     }

     jbyteArray jbArray = env9->NewByteArray((int)propRec->sPropLength);
     env9->SetByteArrayRegion(jbArray, 0, (int)propRec->sPropLength, (jbyte*)propRec->sPropBytes);

     //jobject theClass = env9->FindClass("ob/android/Stream");

     env9->CallVoidMethod(handlerClass, mid, jbArray);

}

这是我的Java代码

public void onResponse(byte[] str) 
    { 
        Log.v("Response", "Java");
    }

我收到了以下崩溃

03-08 16:01:05.915: W/dalvikvm(17552): JNI WARNING: can't call Lob/android/Stream;.onResponse on instance of Ljava/lang/Class;
03-08 16:01:05.915: W/dalvikvm(17552):              in Lob/android/Stream;.stream:()V (CallVoidMethodV)

应用Mah的答案之后,这是我收到的例外

03-08 16:40:20.646: W/dalvikvm(4076): JNI WARNING: JNI method called with exception pending
03-08 16:40:20.646: W/dalvikvm(4076):              in Lob/android/Stream;.stream:()V (NewByteArray)
03-08 16:40:20.646: W/dalvikvm(4076): Pending exception is:
03-08 16:40:20.646: I/dalvikvm(4076): java.lang.NoSuchMethodError: no method with name='onResponse' signature='([B)V' in class Lob/android/Stream;
03-08 16:40:20.646: I/dalvikvm(4076):   at ob.android.Stream.stream(Native Method)
03-08 16:40:20.646: I/dalvikvm(4076):   at ob.android.Stream.<init>(Stream.java:28)
03-08 16:40:20.654: I/dalvikvm(4076):   at ob.android.MainActivity.startRecording(MainActivity.java:203)

现在onResponse方法是静态的。

2 个答案:

答案 0 :(得分:11)

您的Java方法是一种实例方法(非静态方法),但您的本机代码并未引用ob.android.Stream的任何特定实例来调用onResponse()

调用CallVoidMethod()时,第一个参数是你正在运行方法的实例(对象),而不是类本身。如果您使用CallStaticVoidMethod(),则会使用类本身。

答案 1 :(得分:0)

我想为NoSuchMethodError问题添加一个解决方案,虽然可能不是这里的情况,但可能会节省一些大量的调试时间。

对我来说,有一个我必须编辑的proguard配置文件。否则,所有未在java代码中调用的非静态java方法都会被优化,并且本机C ++代码无法找到它们。