"这"在Android JNI中不是有效的JNI引用

时间:2014-06-16 08:53:43

标签: java android android-ndk java-native-interface

我正在使用Android上的Java Native Interface将当前活动传递给本机方法。但我不是使用类似函数名称的JNI。我手动注册本机功能。

有效(JNI命名)。

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


但这确实不起作用。 (作为对象的人工登记和通过活动)

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

错误是

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

其中0xb89a7788是jni侧收到的“this”作为活动。

现在,据我所知,这代表了目前的对象。相当于python中的self。但后来我将一个对象传递给本机,因此它应该是一个有效的引用。为什么无效的参考错误?这不是一个对象吗?怎么了?

1 个答案:

答案 0 :(得分:3)

这不是因为方法的注册方式,而是因为您的原生方法的签名。我会像这样重写那个方法:

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

每个JNI方法都必须以JNIEnv *作为其第一个参数。 (还要注意缺少static env变量 - 它不是必需的)。此外,由于它不是静态方法,因此传入方法的第一个参数将是this而不是activity