从 pthread 初始化对象时"NoSuchMethodError"
"NoSuchMethodError" when initialising object from pthread
我有一个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端开始工作的。
相关文章:
- 没有找到相关文章