简体   繁体   中英

“this” is not a valid JNI reference in Android JNI

I am passing the current activity to the native method using Java Native Interface on android. But I am not doing it using JNI like function names. I am registering native functions manually.

This works (JNI naming).

com_venkatesh_home.c

JNIEXPORT void JNICALL Java_com_venkatesh_Home_doStuff(JNIEnv *env, jobject activity) {
    jclass Activity = (*env)->GetObjectClass (env, activity);

com.venkatesh.Home.java

private native void doStuff();
static {
    System.loadLibrary("venkatesh");
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    doStuff();
 }


But this does not work . (Manual registration and passing activity as an object)

me.c

static JavaVM *java_vm;

void do_stuff (jobject activity)
{
    JNIEnv *env;
    if ((*java_vm)->GetEnv(java_vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        LOG_D("GetEnv failed");
        return -1;
    }

    jclass Activity = (*env)->GetObjectClass (env, activity);
}

jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
    java_vm = vm;

    JNIEnv* env;
    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        LOG_D ("GetEnv failed.");
        return -1;
    }

    // Find the class calling native function
    jclass Home = (*env)->FindClass(env, "com/venkatesh/Home");
    if (Home == NULL) {
        LOG_D ("FindClass failed : No class found.");
        return -1;
    }

    // Register native method for getUsbPermission
    JNINativeMethod nm[1] = {
        { "doStuff", "(Landroid/app/Activity;)V", do_stuff}
    };

    if ((*env)->RegisterNatives(env, NativeUsb, nm , 1)) {
         LOG_D ("RegisterNatives Failed.");
         return -1;
    }

    return JNI_VERSION_1_6;
}

com.venkatesh.Home.java

private native void doStuff(Activity activity);
static {
    System.loadLibrary("venkatesh");
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    doStuff(this);
 }

The error is

JNI WARNING: 0xb89a7788 is not a valid JNI reference (GetObjectClass)

where 0xb89a7788 is the "this" received on jni side as activity.

Now, as I understand this represents the present object. Equivalent to self in python. But then I am passing an object to the native side and hence it should be a valid reference. Why the invalid reference error? It this not an object? What is wrong?

This is happening not because of how the method is being registered, but because of the signature of your native method. I would rewrite that method like this:

void do_stuff (JNIEnv *env, jobject this, jobject activity)
{
    jclass Activity = (*env)->GetObjectClass (env, activity);
    // ...and whatever else you want...
}

Every JNI method must take a JNIEnv * as its first parameter. (Note also the lack of the static env variable - it isn't needed). Also, since it is not a static method, the first parameter passed in to the method will be this and not activity .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM