Chiamare membro del codice JAVA dal codice Native C / C ++

Sto scrivendo un'applicazione OpenGL C / C ++ che sto portndo su Android tramite Android NDK, supporto JNI. Ho difficoltà a eseguire il codice dalla chiamata JAVA segnalata da nativo.

Ecco il codice:

  • Avvisi Il tuo apk sta utilizzando autorizzazioni che richiedono una politica sulla privacy: (android.permission.READ_PHONE_STATE)
  • È ansible utilizzare GCM senza l'account Google ei servizi di Google Play sul dispositivo?
  • Misbehavior quando si tenta di memorizzare una string impostata utilizzando SharedPreferences
  • cercando di submit l'intenzione ad altre app: error SecurityException: Denial of Permission: avviare Intent
  • Ottenere la posizione corrente utilizzando GPS in Android
  • Come distriggersre una barra di avanzamento anche se non è visualizzata la visualizzazione in FirebaseListAdapter?
  • class OpenGLSurfaceView extends GLSurfaceView { … public OpenGLSurfaceView(Context context, int deviceWidth, int deviceHeight) { super(context); nativeObj = new NativeLib(); mRenderer = new OpenGLRenderer(context, nativeObj, deviceWidth, deviceHeight); setRenderer(mRenderer); setRenderMode(RENDERMODE_WHEN_DIRTY); } … private void CallBack() { // force redraw requestRender(); } } class OpenGLRenderer implements GLSurfaceView.Renderer { … public void onSurfaceCreated(GL10 gl, EGLConfig config) { nativeObj.init(…); nativeObj.cachejavaobject(JNIEnv *env, jobject obj); // for caching obj on native side } public void onSurfaceChanged(GL10 gl, int w, int h) { } public void onDrawFrame(GL10 gl) { nativeObj.draw(…); } } 

    E nel codice nativo ho una function texturesLoaded () che viene segnalata quando alcune texture vengono caricate completamente su un altro thread e devo forzare un aggiornamento da nativeLib.draw (…) sul lato JAVA. Ecco come faccio io:

    Cache il JavaVM, jClass, jMethodID su JNI_OnLoad e gJObjectCached

     JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { gJVM = jvm; // cache the JavaVM pointer LogNativeToAndroidExt("JNILOAD!!!!!!!!!!"); JNIEnv *env; int status = gJVM->GetEnv((void **)&env, JNI_VERSION_1_6); if(status < 0) { LogNativeToAndroidExt("Failed to get JNI environment, assuming native thread"); status = gJVM->AttachCurrentThread(&env, NULL); if(status < 0) { LogNativeToAndroidExt("callback_handler: failed to attach current thread"); return JNI_ERR; } } gJClass = env->FindClass("com/android/newlineactivity/NewLineGLSurfaceView"); if(gJClass == NULL) { LogNativeToAndroidExt("Can't find Java class."); return JNI_ERR; } gJMethodID = env->GetMethodID(gJClass, "callback", "()V"); if(gJMethodID == NULL) { LogNativeToAndroidExt("Can't find Java method void callback()"); return JNI_ERR; } return JNI_VERSION_1_6; 

    }

     JNIEXPORT void Java_com_android_OpenGL_NativeLib_cachejavaobject(JNIEnv* env, jobject obj) { // cache the java object gJObjectCached = obj; ... } 

    e poi su texturesLoaded () faccio:

     void texturesLoaded() { // Cannot share a JNIEnv between threads. You should share the JavaVM, and use JavaVM->GetEnv to discover the thread's JNIEnv JNIEnv *env = NULL; int status = gJVM->GetEnv((void **)&env, JNI_VERSION_1_6); if(status < 0) { LogNativeToAndroidExt("callback_handler: failed to get JNI environment, assuming native thread"); status = gJVM->AttachCurrentThread(&env, NULL); if(status < 0) { LogNativeToAndroidExt("callback_handler: failed to attach current thread"); return; } } LogNativeToAndroidExt("Calling JAVA method from NATIVE C/C++"); env->CallVoidMethod(gJObjectCached, gJMethodID); LogNativeToAndroidExt("DONE!!!"); } 

    Risultato … dal lato nativo ottengo la class, ottengo il metodo, il metodo viene chiamato, ma quando raggiunge / chiama requestRender () all'interno (o cerca di accedere a qualsiasi altro metodo membro di GLSurfaceView si blocca!)

    Non posso provare con CallStaticVoidMethod (gJClass, gjMethodID); perché quindi non ho accesso a requestRender ();

    Qualche idea o opinione, forse sto facendo qualcosa di sbagliato qui.

    Grazie

  • App Android compatibile con 0 dispositivi
  • Eccezione di memory exception dovuta alla grande dimensione bitmap
  • La list di Android mostra solo un elemento
  • Come aggiungere il file jar nel path di creazione
  • Come generare un codice QR per un'applicazione Android?
  • OnCameraChangeListener () è deprecata
  • One Solution collect form web for “Chiamare membro del codice JAVA dal codice Native C / C ++”

    È necessario creare riferimenti globali alla class / object che si nasconde. I riferimenti che state salvando sono riferimenti locali , che non possono essere condivisi nei thread e scompaiono quando il runtime ripulisce lo stack di riferimento locale JNI.

    Controllare la documentazione Sun / Oracle per riferimenti globali e locali e verificare i methods JNI JNIEnv::NewGlobalRef e JNIEnv::DeleteGlobalRef .

     gJClass = env->NewGlobalRef(env->FindClass( ... )); gJObjectCached = env->NewGlobalRef(obj); 

    (Modifica: scopre che non è necessario riferimento globale per gli ID metodo.)

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.