After upgrading my phone to android 4.03 ics my game dosent open anymore ,it just closes without any error messege on deviCe and with this on eclipse
04-02 16:
While Ernest's answer is technically correct, a stale local reference to something like 0x1 should hint you that the Java VM is trying to use something that's not a Java object as a Java object.
For example, let's assume your JNI function is:
JNI_EXPORT jboolean foobar(JNIEnv *env, jobject self) {
...
return JNI_TRUE;
}
but you erroneously declare the Java counterpart as public native Boolean foobar()
instead of public native boolean foobar()
.
It's an easy mistake to make, since the only difference between boolean
and Boolean
is capitalization.
boolean
, a primitive type, is represented in JNI as boolean
java.lang.Boolean
, known also as Boolean
, is a class type that is represented in JNI as jobject
Upon return from foobar
, the Java VM will treat the JNI_TRUE
value (0x1) as if it referred to a java.lang.Boolean
object, which will result in this fatal error.
This is a variation on Ernest's answer, instead of passing a Boolean or even a boolean as an argument to the call method, I passed the literal true ( yes I did kick myself repeatedly when I found that) which of course has the value of 0x1.
While not challenging the validity of the other answers, I lost hours chasing these errors. In my case they were truly cryptic but I've only myself to blame:
10-16 12:24:18.722: E/dalvikvm(1204): JNI ERROR (app bug): attempt to use stale global reference 0x26
10-16 12:24:18.722: E/dalvikvm(1204): VM aborting
For me, this meant I hadn't requested the correct permission in the manifest.
@Ernest and @Ilya are correct. Note that the problem manifests itself in other ways too, not just signature mismatches. There is another very specific case that I ran into, which was explained here in the Android' team's blog under the section:
Bug: Mistakenly assuming FindClass() returns global references
FindClass() returns local references. Many people assume otherwise. In a system without class unloading (like Android), you can treat jfieldID and jmethodID as if they were global. (They’re not actually references, but in a system with class unloading there are similar lifetime issues.) But jclass is a reference, and FindClass() returns local references. A common bug pattern is “static jclass”. Unless you’re manually turning your local references into global references, your code is broken.
Basically I was caching the jclass
returned by FindClass
in a global variable as is, but it turns out this value (as of Android 4?) is now a localref. As a result, I had to convert it into a globalref like so:
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));
After a lot of head-scratching, this fixed the issue for me.
In my case I missed passing some arguments required for the constructor(also may apply to calling methods) when calling NewObject
.
The "stale local reference" error means that you're saving a local reference to some Java object between JNI calls; you need to convert that reference to a global reference using the NewGlobalRef
method before doing anything that would cause the reference to persist outside the scope of the one JNI call.
Although strictly this was always necessary -- it's in the JNI spec -- it's only since Ice Cream Sandwich that this actually causes problems on the Android platform.