resueltos procesos partes paralelos los hilos fuente ejemplos definicion codigo caracteristicas java android c++ android-ndk java-native-interface

procesos - partes de un hilo en java



Llamando a un objeto java guardado a través de JNI desde un hilo diferente (1)

Acceder al objeto desde diferentes hilos está bien. El problema es que las llamadas JNI obtienen objetos como referencias locales. Si desea mantener la referencia al objeto de trabajo entre las llamadas JNI, necesita hacerla referencia global:

myobj = env->NewGlobalRef(jObj);

Recuerde liberarlo una vez que haya terminado de usarlo, de lo contrario, el recolector de basura no lo recogerá y obtendrá pérdidas de memoria:

myEnv->DeleteGlobalRef(myobj);

Lea sobre referencias globales vs locales here .

Tengo un objeto java que llama a un objeto compartido en C ++ a través de JNI. En C ++, estoy guardando una referencia al JNIEnv y al jObject.

JavaVM * jvm; JNIEnv * myEnv; jobject myobj; JNIEXPORT void JNICALL Java_org_api_init (JNIEnv *env, jobject jObj) { myEnv = env; myobj = jObj; }

También tengo un procesador GLSurface y eventualmente llama al objeto compartido de C ++ mencionado anteriormente en un subproceso diferente, el GLThread. Luego estoy intentando volver a llamar a mi objeto Java original utilizando el trabajo que guardé inicialmente, pero creo que porque estoy en el GLThread, obtengo el siguiente error.

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

El código vuelve a llamar a Java:

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);

}

Si, en cambio, creo un nuevo jObject usando env-> NewObject, puedo volver a llamar a Java con éxito, pero es un nuevo objeto y no quiero eso. Necesito volver a mi objeto Java original.

¿Es cuestión de cambiar los hilos antes de que vuelva a llamar a Java? Si es así, ¿cómo lo hago?