Search code examples
javaandroidjava-native-interface

Calling a static void Java method from JNI


My C code does not manage to find the public static function call I have in Java. It manages to find the class without error.

I am attempting to return a result to a callback method onResponse. "5" will be replaced by something more complex later.

I have seem similar questions on StackOverflow, but no changes so far seem to have helped. Perhaps I have a logic error?

My JNI (updated #2):

void cec_debug_msg(JNIEnv *env, cec_rx_message_t* msg) {
    jclass cls = (*env)->FindClass(env, "com/example/utils/CECUtils");
    if(!cls) {
        LOGE("Could not find the CEC class.");
    } else {
        jmethodID methodid = (*env)->GetStaticMethodID(env, cls, "onResponse", "(I)V");
        if(!methodid) {
            // Code always reaches this point, never finding the method
            LOGE("Could not find the callback method.");
        } else {
            LOGV("Called static void method.");
            (*env)->CallStaticVoidMethod(env, cls, methodid, 5);
        }
    }
}

This code is contained in a method that is called from this function:

JNIEXPORT int JNICALL Java_com_example_utils_CECUtils_startListening(JNIEnv *env, jclass cls) {

    ...

    cec_debug_msg(env, &rx_msg);

    ...

}

My Java (updated #1):

public class CECUtils {

    static {
        System.loadLibrary("cecutils");
    }

    public static native int startListening();

    ...

    public static void onResponse(int opcode) {
        Utils.log("CEC", "From JNI!");
    }

}

Signature check:

javap -s -p CECUtils

public static void onResponse(int);

Signature: (I)V

Solution: Check ProGuard!

-keep public class com.example.utils.CECUtils {
    *;
}

Solution

  • Try using GetStaticMethodID instead of GetMethodID.

    Note, you will need to call CallStaticVoidMethod instead of CallVoidMethod also.

    See here for more info: http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html