2013-04-17 84 views
0

我的應用程序運行下面的代碼:JNI。不同的Android操作系統版本之間的不同的行爲

void BmrDeviceInfo_convertToC(JNIEnv *pEnv, jobject jBmrDeviceInfo, BmrDeviceInfo& cBmrDeviceInfo){ 

__android_log_print(ANDROID_LOG_INFO, "BEAMER_JNI", "g_classBmrDeviceInfo is = %s", (g_classBmrDeviceInfo == NULL) ? "NULL" : "OK"); //g_classBmrDeviceInfo is initialize on JNI_OnLoad 

jfieldID fieldName = pEnv->GetFieldID(g_classBmrDeviceInfo, "m_strName", "Ljava/lang/String;"); // OK for Android 4.2 and crash for Android 3.1 or less 

.................................. 
} 

而且logcat的輸出崩潰的情況:

04-17 16:28:44.118: I/BEAMER_JNI(446): g_classBmrDeviceInfo is = OK 
04-17 16:28:44.118: W/dalvikvm(446): JNI WARNING: 0x4053dc70 is not a valid JNI reference 
04-17 16:28:44.118: W/dalvikvm(446):    in Lcom/xxxxxxx/xxxxxx/controller/CoreController;.Init (Lcom/xxxxxxx/xxxxxx/listviews/DeviceInfo;Ljava/lang/String;)I (GetFieldID) 
04-17 16:28:44.118: I/dalvikvm(446): "main" prio=5 tid=1 RUNNABLE 
04-17 16:28:44.118: I/dalvikvm(446): | group="main" sCount=0 dsCount=0 obj=0x4001f1a8 self=0xce48 
04-17 16:28:44.118: I/dalvikvm(446): | sysTid=446 nice=0 sched=0/0 cgrp=default handle=-1345006528 
04-17 16:28:44.118: I/dalvikvm(446): | schedstat=(276745040 468907344 84) 

感謝您的幫助!

+0

檢查這個http://stackoverflow.com/questions/11907832/jni-local-vs-global-reference-is-not-a-valid-jni-reference – Pragnani

+0

看起來像很多改變4 1實現類改變從c https://android.googlesource.com/platform/dalvik/+/gingerbread/vm/Jni.c到C++ https://android.googlesource.com/platform/dalvik/+/master/vm/Jni.cpp而且還有很多更改。看起來最早的版本是4.1.1左右。這可能有點解釋你的問題。現在我不是一個很棒的C人,所以你可以看看它,你可以看到它的差異。沒有任何東西出現在我身上。 – Jackie

回答

2

接受對象的JNI函數需要本地或全局引用。前ICS這些都是原始指針,但是在ICS中改爲表格索引系統。

你不說在問題中用什麼版本來生成輸出。十六進制值0x4053dc70看起來像一個原始指針,所以我假設這是前ICS。查看錯誤消息,看起來g_classBmrDeviceInfo無效;導致此錯誤的常見方法是無法使用NewGlobalRef將本地引用轉換爲全局引用。

一般來說,JNI變成了更多在ICS中是嚴格的,所以它很奇特,它會在4.x中成功,但在3.x中失敗,除非你玩弄弱的全局變量。

+0

我不確定我是否自己跟着這個,你知道源代碼在哪裏發生了變化嗎? – Jackie

+0

NM這解釋了它更多一點... http://android-developers.blogspot.com/2011/11/jni-local-reference-changes-in-ics.html。所以基本上他使用的是ref,當他以後試圖訪問它時(在ICS之前),該對象已經被GC移動,因此是無效的。基本上是這樣嗎? – Jackie

+1

達爾維克GC,至少通過軟糖,不移動物體。 Class對象永遠不會被丟棄,所以這個失敗看起來像是一個糟糕的全局或者只是一個完全不好的指針。 ICS之前的CheckJNI實現試圖通過在全局和本地ref表中搜索引用來檢查對象的有效性,但是有可能「僞造」這一點。 > = ICS「間接引用」方法更加準確,並且由於不再提供原始指針,因此允許GC移動對象(這是工作的主要動機)要容易得多。 – fadden

相關問題