【问题标题】:JNI method doesn't callback Java methodJNI 方法不回调 Java 方法
【发布时间】:2014-11-04 17:30:56
【问题描述】:

已解决:我需要在调用方法之前创建一个新对象!

我一直在尝试从 JNI 调用 Java 方法。调用有效,应用程序不会崩溃,但 JAVA 方法也不会被调用。

对我做错了什么有什么想法吗?

我的 JNI 代码:

jclass test_method = findClass("com/package/Test");

if (test_method == NULL) {
    __android_log_print(ANDROID_LOG_ERROR, "JNI", "failed to find test");
} else {
    __android_log_print(ANDROID_LOG_ERROR, "JNI", "found test object");
}
jmethodID test_const =  env->GetMethodID(test_method, "<init>", "(I)V");

jobject employeeObject = (env)->NewObject(test_method, test_const, 800);

if (employeeObject == NULL) {
    __android_log_print(ANDROID_LOG_ERROR, "JNI", "failed to find object");
} else {
    __android_log_print(ANDROID_LOG_ERROR, "JNI", "found emp object");
}
jclass myclass = findClass("com/package/TestObj");

if(myclass == NULL) {
    __android_log_print(ANDROID_LOG_ERROR, "JNI", "Couldnt find myclass");
    return;
} else {
    __android_log_print(ANDROID_LOG_ERROR, "JNI", "Found myclass");
}

g_clazz = (jclass)env->NewGlobalRef(myclass);

if (g_clazz == NULL) {
    fLogPrintf(LOG_DEBUG,"Failed to find class");
}
new_method = env->GetMethodID(g_clazz, "setParams", "(Lcom/package/Test;)V");

if (new_method == 0) {
    __android_log_print(ANDROID_LOG_ERROR, "JNI", "failed to find method");
}

(*env).CallVoidMethod(g_clazz, new_method, employeeObject);
__android_log_print(ANDROID_LOG_ERROR, "JNI", "succesfully finished  calling method");
if (env->ExceptionCheck()) {
    env->ExceptionDescribe();
}

__android_log_print(ANDROID_LOG_ERROR, "JNI", "Detaching current thread");
m_jvm->DetachCurrentThread();

我的 Java 代码:

package com.package; 

class TestObj { 
    public void setParams(Test test) {
        Log.e("Oops", " Callback successfully called!");
    }
}

当我运行应用程序时,它运行完美,没有任何错误/崩溃,我还得到“成功完成调用方法”和“分离当前线程”日志,这表明 JNI 能够成功调用我的函数,但是当我检查日志时对于 Java 方法 setParams,我根本看不到任何日志。

知道我错过了什么吗?

谢谢

【问题讨论】:

  • new_method = env->GetMethodID(g_clazz, "setParams", "(Lcom/package/Test;)V");我认为您在这一行中的论点是错误的,应该 Test 是 TestSIP 吗?
  • 糟糕,这是一个错字,它应该是测试。更新了问题。另外我不认为命名是问题,因为如果命名错误,它通常不会崩溃。我把所有的日志都写到最后
  • env->GetMethodID 不返回对象,但如果未找到该方法,则返回 0,您应该对此进行检查。 NULL 检查不起作用,因为它从不返回 NULL。
  • 刚刚试了一下,没有返回0,所以找到了方法
  • 是的,所有方法都找到了。我将所有方法检查从 NULL 替换为 0。它找到了所有方法,这是更令人困惑的部分。我不明白这是怎么回事

标签: android callback java-native-interface


【解决方案1】:

我需要在调用方法之前创建一个新对象!所以我只是在调用方法之前添加了以下代码行:

jmethodID constructor = env->GetMethodID(g_clazz, "<init>", "(I)V"); 
jobject test_object = env->NewObject(g_clazz, constructor, 48);

然后最后将方法的最终调用修改为:

(*env).CallVoidMethod(test_object, new_method, 23);

之前的调用是错误的:

(*env).CallVoidMethod(g_clazz, new_method, 23);

使用 g_clazz 是个问题

【讨论】:

  • 这没有意义。如果您还没有对象,为什么还要调用实例方法?
  • 我试图使用返回给我的类调用函数,但我不得不显式创建一个新对象并使用该对象调用该方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多