Mam obiekt java, który wywołuje obiekt współdzielony w C++ przez JNI. W C++ zapisuję odniesienie do JNIEnv i jObject.Wywołanie zapisanego obiektu Javy przez JNI z innego wątku
JavaVM * jvm;
JNIEnv * myEnv;
jobject myobj;
JNIEXPORT void JNICALL Java_org_api_init
(JNIEnv *env, jobject jObj) {
myEnv = env;
myobj = jObj;
}
Mam również rendererz GLSurface i ostatecznie wywołuje współużytkowany obiekt C++ wspomniany powyżej w innym wątku, GLThread. Próbuję następnie wywołać z powrotem do mojego pierwotnego obiektu Java przy użyciu jobject I zapisane początkowo, ale Myślę, że ponieważ jestem na GLThread, otrzymuję następujący błąd.
W/dalvikvm(16101): JNI WARNING: 0x41ded218 is not a valid JNI reference
I/dalvikvm(16101): "GLThread 981" prio=5 tid=15 RUNNABLE
I/dalvikvm(16101): | group="main" sCount=0 dsCount=0 obj=0x41d6e220 self=0x5cb11078
I/dalvikvm(16101): | sysTid=16133 nice=0 sched=0/0 cgrp=apps handle=1555429136
I/dalvikvm(16101): | schedstat=(0 0 0) utm=42 stm=32 core=1
Kod oddzwanianie w Javie:
void setData()
{
jvm->AttachCurrentThread(&myEnv, 0);
jclass javaClass = myEnv->FindClass("com/myapp/myClass");
if(javaClass == NULL){
LOGD("ERROR - cant find class");
}
jmethodID method = myEnv->GetMethodID(javaClass, "updateDataModel", "()V");
if(method == NULL){
LOGD("ERROR - cant access method");
}
// this works, but its a new java object
//jobject myobj2 = myEnv->NewObject(javaClass, method);
//this is where the crash occurs
myEnv->CallVoidMethod(myobj, method, NULL);
}
Jeśli zamiast tworzyć nowy jObject korzystając env-> NewObject mogę succuessfully oddzwonić do Javy, ale jest nowy obiekt i nie chcę tego. Muszę wrócić do mojego oryginalnego obiektu Java.
Czy to kwestia zmiany wątków przed ponownym wywołaniem w Javie? Jeśli tak, jak mam to zrobić?
działa idealnie! –
Zobacz także http://developer.android.com/training/articles/perf-jni.html dla tego i innych wskazówek. – fadden
Dziękuję ... Proste i działa doskonale –