Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android's CheckJNI: How to turn it off/on (on an emulator)? Documentation seems to be faulty

I have spent some time examining the checkjni mode using an Android emulator with my app. Altough it is written (in http://android-developers.blogspot.com/2011/11/jni-local-reference-changes-in-ics.html) that CheckJNI is on by default if debuggable="true" & targetSdkVersion is at least Ice Cream Sandwich (in the AndroidManifest.xml file) - The debug output dump of the CheckJNI (warning and errors) is still printed in the DDMS, even if i use a Gingerbread values and install it on a Gingerbread emulator.

The only difference that i have found is that CheckJNI warnings on an Ice Cream Sandwich emulator (no matter what were the values in my AndroidManifest.xml file) will cause the app to crash with the respected warning - while they would only be printed in a Gingerbread emulator (I have tested a DeleteGlobalRef used on local reference to induce this warning).

There are two non-informational logs that are printed in accordance to the AndroidManifest.xml - But the logs of the of the CheckJNI mode are not affected.

Here are the logs -

#On ICS emulator After Installing the app:

 01-19 08:43:01.491: D/AndroidRuntime(32): CheckJNI is ON

Loading the app:
01-19 08:32:26.617: D/dalvikvm(590): Not late-enabling CheckJNI (already on)

(The last line is printed only when debuggable="true")

01-19 08:32:27.066: I/dalvikvm(590): Turning on JNI app bug workarounds for target SDK version 10...

(The last line is printed only when targetSdkVersion=10)

On error code (crash):

01-19 08:37:56.176: W/dalvikvm(651): JNI WARNING: DeleteGlobalRef on non-global 0x41339550 (type=1)

...

01-19 08:37:56.187: E/dalvikvm(651): VM aborting

01-19 08:37:56.187: A/libc(651): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1)

#On Gingerbread:

After Installing the app:

01-19 08:43:01.491: D/AndroidRuntime(32): CheckJNI is ON

Loading the app:

No important logs

On error code (no crash):

01-19 08:45:20.079: W/dalvikvm(304): JNI: DeleteGlobalRef(0x40608718) failed to find entry (valid=1)

So my question is how should i turn it on/off - and how should it affect the application (or the logs) differently when on?

Thanks.

like image 341
Jon Bonbon Jovi Avatar asked Jan 18 '12 14:01

Jon Bonbon Jovi


1 Answers

The emulator is special. CheckJNI is always on in the emulator.

Adding to your confusion, the DeleteGlobalRef warning you show wasn't part of CheckJNI pre-ICS. It was basically a bit of debugging output in the old local/global reference implementation. As part of the ICS work, that was moved into CheckJNI, where it should probably always have been.

So all the behavior you're seeing is "expected" in the literal sense, even if it's somewhat surprising!

If you look at http://developer.android.com/guide/practices/design/jni.html you might be able to turn CheckJNI off in the emulator, though I'm not sure why you'd want to, so I'm not going to encourage you any further than that! What you really want to do is fix any JNI bugs you have, to ensure that your apps keep working on future versions of Android :-)

(I'm disappointed by the quality of my "JNI WARNING: DeleteGlobalRef on non-global 0x41339550 (type=1)" diagnostic --- I'll see about being more specific than "non-global" and removing the "type=1", which should at least match the numeric value of one of the reference types in <jni.h>'s enum.)

If you're poking around in this area, see also http://code.google.com/p/android/issues/detail?id=21674 --- backwards compatibility for global references doesn't work; only local references. So if setting targetSdkVersion low isn't working for you, it might be because we're handing out indirect global references anyway (even though local references will be direct).

like image 101
Elliott Hughes Avatar answered Sep 29 '22 20:09

Elliott Hughes