2011-04-21 33 views
6

在Android上使用java本地接口時,我犯了兩個愚蠢的錯誤,這會花費我很多時間。方法簽名和實際調用之間的錯配

有了這個方法ID:

jmethodID myMethod_methodID = env->GetMethodID(hello_Cls, "myMethod", "(ILjava/lang/String;Ljava/lang/String;I)Z"); 

我的第一個錯誤是使用

env->CallVoidMethod 

調用它,我的第二個錯誤是在調用它像這樣

jboolean rv = jenv->CallBooleanMethod(hello_obj, myMethod_methodID, myfirst_jstring, mysecond_jstring, 1); 

這是明顯缺失myMethod_methodID和之間的參數。

我花了很長時間來跟蹤這些錯誤,因爲logcat中沒有相關的輸出,唯一的行爲沒有做任何事情(它甚至沒有崩潰)。

因此,問題是:如何爲這類錯誤獲得更有意義的錯誤?

回答

4

本頁面可能是有用的:http://www.netmite.com/android/mydroid/dalvik/docs/jni-tips.html,特別是:

JNI幾乎不做錯誤檢查。在對象字段上調用SetFieldInt將會成功。我們的目標是儘量減少開銷,前提是如果您使用本機代碼編寫代碼,則可能是出於性能方面的考慮。

某些虛擬機支持使用「-Xcheck:jni」標誌進行擴展檢查。如果該標誌被設置,則VM將不同的函數表放入JavaVM和JNIEnv指針中。這些函數在調用標準實現之前進行了一系列擴展檢查。

有些事情可以驗證:

  • 檢查空指針,其中不允許的。
  • 驗證參數類型的正確性(jclass是一個類對象,jfieldID指向字段數據,jstring是一個java.lang.String)。
  • 字段類型的正確性,例如不要在String字段中存儲HashMap。
  • 檢查在掛起異常不合法的調用中是否有異常掛起。
  • 檢查關鍵獲取/釋放呼叫之間的不適當功能調用。
  • 檢查JNIEnv結構是否不在線程之間共享。
  • 確保在允許的使用壽命之外不使用本地引用。
  • UTF-8字符串包含有效的「修改的UTF-8」數據。

未檢查方法和字段(即公共與私人)的可訪問性。

繼鏈接:http://www.netmite.com/android/mydroid/dalvik/docs/embedded-vm-control.html

您可以設置ADB如下:

adb shell setprop dalvik.vm.checkjni true 
adb shell setprop dalvik.vm.execution-mode int:debug 
+0

感謝您的信息! :)只是爲了完成提供的信息:**這不適用於設備**,除非它們是根植的。 (我花了一些時間試圖在設備上這樣做,直到我明白了)。 – 2011-05-03 12:04:39

+0

更正:根植設備讓您啓用標誌,但檢查並沒有在模擬器中完成(即使您可以讀取'D/AndroidRuntime(3455):D/AndroidRuntime(3455):>>>>>>>>> >>>>> AndroidRuntime START <<<<<<<<<<<<<< D/AndroidRuntime(3455):日誌中的CheckJNI爲ON') – 2011-05-03 16:08:46

+1

@João您以前看過這兩個鏈接嗎?這篇文章:http://vilimpoc.org/blog/2010/09/23/hello-gdbserver-a-debuggable-jni-example-for-android/和sequoyah pligin:http://www.eclipse.org/ sequoyah/documentation/native_debug.php – Aleadam 2011-05-05 20:11:28

相關問題