2013-02-08 47 views
10

我從書Android應用程序絕對初學者和溫度轉換器應用程序from here 這兩個在模擬器上運行良好,但當我嘗試三星注2以下錯誤運行它在logcat的到來JNI錯誤(應用程序錯誤):訪問陳舊的本地參考0xbc00021(8號表中的索引8)

02-08 07:22:18.665: E/dalvikvm(30944): JNI ERROR (app bug): accessed stale local reference 0xbc00021 (index 8 in a table of size 8) 
02-08 07:22:18.665: E/dalvikvm(30944): VM aborting 
02-08 07:22:18.665: A/libc(30944): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 30944 (oid.temperature) 

兩個程序做標題開節目佈局,但不顯示在佈局其他任何意見

樣品運行良好

設備:注2:三星gt_n7100

IDE:Eclipse的3.8版本

OS:64位Windows 7

+1

看看:http://android-developers.blogspot.cz/2011/11/jni-local-reference-changes-in-ics.html –

回答

55

由於Android 4.0的垃圾收集器被改變。現在它在垃圾回收期間移動對象,這會導致很多問題。

想象一下,你有一個靜態變量指向一個對象,然後這個對象被gc移動。由於android使用java對象的直接指針,這意味着你的靜態變量現在指向內存中的一個隨機地址,不被任何對象佔用或被不同類型的對象佔用。這幾乎可以保證你下次使用這個變量時會得到EXC_BAD_ACCESS。

所以android會給你JNI ERROR(應用程序bug)錯誤,以防止你獲取不可取消的EXC_BAD_ACCESS。現在有兩種方法可以避免這種錯誤。

  1. 您可以將清單中的targetSdkVersion設置爲版本11或更低版本。這將啓用JNI缺陷兼容模式並完全防止出現任何問題。這就是你的老例子工作的原因。

  2. 你能避免使用指向Java對象靜態變量或致電env-> NewGlobalRef(REF)存儲在他們面前做出jobject引用了全局。
    也許在這裏最大的例子是保持jclass對象。通常,您將在JNI_OnLoad期間初始化靜態jclass變量,因爲只要應用程序正在運行,類對象就會保留在內存中。

此代碼將導致崩潰:

static jclass myClass; 

JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM * vm, void * reserved) { 
    myClass = env->FindClass("com/example/company/MyClass"); 
    return JNI_VERSION_1_6; 
} 

儘管此代碼將運行正常:

static jclass myClass; 

JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM * vm, void * reserved) { 
    jclass tmp = env->FindClass("com/example/company/MyClass"); 
    myClass = (jclass)env->NewGlobalRef(tmp); 
    return JNI_VERSION_1_6; 
} 

更多的例子看到馬立克Sebera提供的鏈接:http://android-developers.blogspot.cz/2011/11/jni-local-reference-changes-in-ics.html

+5

儘管如此,這應該在Android的FrontPage上進行。現在我想知道有多少成千上萬的本地應用的可能randomnly因爲這個問題,耶穌... – RelativeGames

+0

@Alexey隊友即時通訊新到Android崩潰,並面臨同樣的問題http://stackoverflow.com/questions/21423036/sqlite3- exception-database-disk-image-is-malformed請告訴我如何實現你的代碼..從最後3周糾正它:( – Gattsu

+0

@ManishYadav圍繞sqlite庫jni包裝可能有同樣的錯誤,我在這裏談論,但我不能肯定地說沒有看jni(c端)包裝本身。你真的應該在你的問題中附加java-side和c-side jni代碼。還有,你是否考慮在sqlite中使用android standart wrapper?它很快,並且幾乎可以滿足任何需求(除非本地化的非英語搜索,自定義索引和其他幾個很少用到的東西) – Alexey

相關問題