2011-04-21 66 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

相关问题