Подтвердить что ты не робот

Android NDK: вызов java-метода из класса JNI C

У меня есть метод 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)

После применения ответа Маха, вот исключение, которое я получаю

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 является статическим.

4b9b3361

Ответ 1

Ваш метод Java - это метод экземпляра (не статический), но ваш собственный код не относится к какому-либо конкретному экземпляру ob.android.Stream для вызова onResponse() для.

При вызове CallVoidMethod() первым параметром должен быть экземпляр (объект), с которым вы запускаете метод, а не сам класс. Сам класс будет использоваться, если вы используете CallStaticVoidMethod().

Ответ 2

Я хотел бы добавить еще одно решение проблемы NoSuchMethodError, хотя, возможно, это и не так, может спасти некоторых из вас много часов отладки.

Для меня был файл конфигурации proguard, который мне пришлось редактировать. В противном случае все нестатические java-методы, которые не вызывают в java-коде, оптимизируются, а собственный С++-код не может их найти.