Android ICS: intento de error JNI para usar referencia local obsoleta 0x1
Después de actualizar mi teléfono a Android 4.03 ics mi juego dosent abrir más, sólo se cierra sin ningún error messege en deviCe y con esto en eclipse
04-02 16:55:27.672: E/dalvikvm(26884): JNI ERROR (app bug): attempt to use stale local reference 0x1 04-02 16:55:27.672: E/dalvikvm(26884): VM aborting
Mi juego se escribe principalmente en java pero algunas partes están en c y eso fue que creo que el problema es (no es muy difícil de averiguar desde su diciendo JNI ERROR :))
- ¿Cuál es la forma correcta de usar v8 :: Locker, y por qué debo usarlo?
- Android ndk jni Ninguna implementación encontrada error
- Devolver un int de la función nativa (c ++, jni) bloquea la aplicación
- Comportamiento sorpresa de eclipse para archivos C mientras se utiliza JNI, ¿Por qué?
- Android NDK R8E falta stdlib.h
Por supuesto que no sé dónde está el problema, así que no dar ningún código
No tuve este problema en android 2.3
No sé si esto ayuda, pero también tengo este error
04-02 16:55:26.061: E/Adreno200-ES11(26884): <qglDrvAPI_glTexImage2D:1913>: GL_STACK_UNDERFLOW
- JNI se bloquea al llamar a CallVoidMethod
- Cómo agregar un servicio de sistema a Android Framework
- No se encontró JNI_OnLoad en ... saltando init
- Cómo devolver array int de Java a JNI
- ¿El enlace JavaScript de JNI de Android pasa eficientemente TypedArray / ArrayBuffer a Java como una matriz?
- Biblioteca binaria preconfigurada nativa en Android Studio con el complemento experimental de Gradle
- Qt para Android - el equivalente de startActivityForResult no funciona
- Unsatisfiedlinkerror en android (eclipse)
Aunque la respuesta de Ernest es técnicamente correcta, una referencia local obsoleta a algo como 0x1 debería sugerir que la máquina virtual Java intenta utilizar algo que no es un objeto Java como objeto Java.
Por ejemplo, supongamos que su función JNI es:
JNI_EXPORT jboolean foobar(JNIEnv *env, jobject self) { ... return JNI_TRUE; }
Pero declaras erróneamente la contraparte de Java como public native Boolean foobar()
public native boolean foobar()
lugar de public native boolean foobar()
.
Es un error fácil de hacer, ya que la única diferencia entre boolean
y Boolean
es la capitalización.
-
boolean
, un tipo primitivo, se representa en JNI comoboolean
-
java.lang.Boolean
, conocido también comoBoolean
, es un tipo de clase que se representa en JNI comojobject
Al regresar de foobar
, la VM Java tratará el valor JNI_TRUE
(0x1) como si se refiriera a un objeto java.lang.Boolean
, que resultará en este error fatal.
El error de "referencia local obsoleta" significa que está guardando una referencia local a algún objeto Java entre llamadas JNI; NewGlobalRef
convertir esa referencia a una referencia global utilizando el método NewGlobalRef
antes de hacer cualquier cosa que haga que la referencia persista fuera del ámbito de una llamada JNI.
Aunque estrictamente esto siempre fue necesario – es en la especificación JNI – es sólo desde Ice Cream Sandwich que esto realmente causa problemas en la plataforma Android.
@Ennest y @Ilya son correctas. Tenga en cuenta que el problema se manifiesta de otras formas también, no sólo las discrepancias de firma. Hay otro caso muy específico en el que me encontré, que fue explicado aquí en el blog del equipo de Android bajo la sección:
Bug: Asumiendo equivocadamente que FindClass () devuelve referencias globales
FindClass () devuelve referencias locales. Muchas personas asumen lo contrario. En un sistema sin descarga de clase (como Android), puede tratar jfieldID y jmethodID como si fueran globales. (En realidad no son referencias, pero en un sistema con descarga de clase hay problemas de vida similares.) Pero jclass es una referencia y FindClass () devuelve referencias locales. Un patrón de error común es "jclass estático". A menos que esté transformando manualmente sus referencias locales en referencias globales, su código está roto.
Básicamente, estaba caché de la jclass
devuelto por FindClass
en una variable global como es, pero resulta que este valor (a partir de Android 4?) Es ahora un localref. Como resultado, tuve que convertirlo en un globalref así:
jclass jc = env->FindClass(callbacks.name); // Since Android ICS, class references are not global so we need to peg a // global reference to the jclass returned by FindClass(), otherwise we get // following error in the log: // "JNI ERROR (app bug): attempt to use stale local reference 0xHHHHHHHH". callbacks._class = static_cast<jclass>(env->NewGlobalRef(jc));
Después de un montón de rascarse la cabeza, esto arregló el problema para mí.
Esta es una variación de la respuesta de Ernest, en lugar de pasar un booleano o incluso un booleano como un argumento para el método de llamada, pasé el verdadero literal (sí me pateó repetidamente cuando lo encontré), que por supuesto tiene el valor de 0x1 .
Aunque no desafío la validez de las otras respuestas, he perdido horas persiguiendo estos errores. En mi caso, eran verdaderamente crípticos, pero sólo tengo que culpar a mí mismo:
10-16 12: 24: 18.722: E / dalvikvm (1204): ERROR JNI (bug de la aplicación): intento de usar la referencia global obsoleta 0x26
10-16 12: 24: 18.722: E / dalvikvm (1204): VM aborting
Para mí, esto significaba que no había solicitado el permiso correcto en el manifiesto.
- Barra de estado de Android desplazándose hacia arriba con el diseño del coordinador, dejando iconos de estado que se superponen al título de la barra de herramientas
- Retroalimentación de RecyclerView + CardView + Touch