10

I have JNI method where I am trying to call Java method. Here is my JNI code

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);

}

Here is the Java code that I have

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

I am receiving following crash

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)

After applying Mah's answer, here is the exception I am receiving

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)

Now onResponse method is static.

1
  • You must check for and handle exceptions after any JNI call that can throw an exception. CallVoidMethod being a prime example. See developer.android.com/training/articles/… Commented Mar 9, 2013 at 0:56

2 Answers 2

11

Your Java method is an instance method (not static), but your native code isn't referring to any specific instance of ob.android.Stream to call onResponse() for.

When calling CallVoidMethod(), the first parameter is to be the instance (object) you're running the method against, not the class itself. The class itself would be used if you were using CallStaticVoidMethod().

Sign up to request clarification or add additional context in comments.

4 Comments

Any chance of getting a little more detail when I change to.. jmethodID method = env->GetMethodID(obj, "playA", "()V"); I see... error: invalid conversion from 'jobject {aka _jobject*}' to 'jclass {aka _jclass*}' [-fpermissive]
@Jackie GetMethodId() wants the class to get the method id from, not an object as you appear to be using. If you don't already have the class for that object available, you can get it from that obj by using GetObjectClass()
Correction: The first argument to CallVoidMethod must be the java environment to run the method in.
@EvanLeis if the calling environment were C you would be correct. Since it's C++ though, the java environment is not the first parameter because it's the object the message is being called against, as in env->CallVoidMethod(). You can tell that C++ is the language at play here from the code in the question.
0

I would like to add one more solution to the NoSuchMethodError problem, that although might not be the case here, might save some of you a lot of hours of debugging.

For me, there was a proguard config file that I had to edit. Otherwise all non-static java methods that aren't called in the java code, get optimized out and the native C++ code isn't able to find them.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.