从 pthread 初始化对象时"NoSuchMethodError"

"NoSuchMethodError" when initialising object from pthread

本文关键字:NoSuchMethodError 对象 pthread 初始化      更新时间:2023-10-16

我有一个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线程中提取方法引用。它运行良好。。。但奇怪的是,一旦我这样做回调中的代码也开始工作

我被难住了。我不知道发生了什么,也不知道下一步该做什么。

到目前为止,我已经将其归结为在其他地方抛出的一个错误,而这正是此类问题的症状。我已经创建了这些方法集,现在在每次调用后都使用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撞车了,它会自行处理,而路上的东西会坏掉。

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

相关文章:
  • 没有找到相关文章