"的NoSuchMethodError"从pthread初始化对象时

时间:2012-03-05 12:37:46

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

我有一个Android / Java应用程序,它通过JNI调用C ++代码来启动阻塞操作。 C ++代码启动一个线程来执行这个阻塞操作,然后它应该在JNI完成时回调。

调用C ++没有任何问题。但是,当回调JNI时,会报告错误的混合。

从新主题获取jclass引用显然不合法。执行该操作会产生“不可预测的行为”,因此所有类查找都在JNI_OnLoad()方法中执行,如下所示:

static jclass sampleClazz;

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

    JNIEnv* env = NULL;
    jint result = jvm->GetEnv((void**)&env, JNI_VERSION_1_6);

    if(env == NULL) { __android_log_print(ANDROID_LOG_DEBUG, "JNI_OnLoad", "NULL");}

    sampleClazz= env->FindClass("com/sample/SampleClazz");
    sampleClazz= (jclass) env->NewGlobalRef(sampleClazz);

    ...etc...
}

在其中一个线程中,我试图回调Java代码。回调方法看起来类似于:

void cCallBackOne() {
    JNIEnv* env;
    jvm->AttachCurrentThreadAsDaemon(&env, NULL);

    jmethodID init = env->GetMethodID(sampleClazz, "<init>", "()V");
    if(init == NULL) { 
        __android_log_print(ANDROID_LOG_DEBUG, "START", "NULL HERE"); 
    } else {
        __android_log_print(ANDROID_LOG_DEBUG, "START", "ALL FINE"); 
    }

不幸的是,由于某些未知的原因,这是记录/投掷:

Exception Ljava/lang/NoSuchMethodError; thrown while initializing Lcom/sample/SampleClazz;
NULL HERE

在处理不同的解决方案时,我尝试将GetMethodId移动到JNI_OnLoad方法,以便查看是否可以从原始Java线程中正确提取方法引用。它运行正常...但奇怪的是,一旦我这样做 回调中的代码也开始工作

我非常难过。我不知道发生了什么,不知道下一步该尝试什么。

2 个答案:

答案 0 :(得分:0)

到目前为止,我已将其归结为在其他地方被抛出的错误,这是这种问题的症状。我创建了这些方法集,现在每次调用后都使用check()

void check(jclass toCheck) {
    if(toCheck == NULL) {
        __android_log_print(ANDROID_LOG_ERROR, "Check", "Error retrieving jclass");
    }
}

void check(jmethodID toCheck) {
    if(toCheck == NULL) {
        __android_log_print(ANDROID_LOG_ERROR, "Check", "Error retrieving jmethodID");
    }
}

void check(jfieldID toCheck) {
    if(toCheck == NULL) {
        __android_log_print(ANDROID_LOG_ERROR, "Check", "Error retrieving jfieldID");
    }
}

void check(jobject toCheck) {
    if(toCheck == NULL) {
        __android_log_print(ANDROID_LOG_ERROR, "Check", "Error retrieving jobject");
    }
}

到目前为止,添加这些检查已经解决了我的问题...为了理智,我希望除了“魔术”之外还有一个理由可以解释为什么会这样......

我担心,虽然我不得不承认在代码执行中早先抛出了一些奇怪的异常,这只是早期崩溃的症状。

课程:记得给代码人员隔离!如果JNI崩溃了它就会让它自己保持下去,而不管怎么说就会破坏它。

答案 1 :(得分:0)

我知道这是很久以前的事了但是,我遇到了同样的问题。我发现我的Java类没有在任何Java代码中使用,因此它正在被优化。我在我的应用程序中使用了Java类,它现在都可以在C方面工作。