因此GetMethodID()上的文档说:
返回方法ID,如果找不到指定的方法,则返回NULL。
但是,在Android上似乎并非如此,因为使用不存在的方法名称调用GetMethodID()
总是会引发致命异常并杀死整个线程。考虑以下代码:
jmethodID id = (*env)->GetMethodID(env, mActivityClass, "iDontExist", "()V");
这将导致完整的线程崩溃,并在Logcat上显示以下输出:
01-26 15:11:30.210 6403 6507 F art : art/runtime/thread.cc:1657] No pending exception expected: java.lang.NoSuchMethodError: no non-static method "Lcom/example/test/TestActivity;.iDontExist()V"
01-26 15:11:30.210 6403 6507 F art : art/runtime/thread.cc:1657] at void com.example.test.TestActivity.nativeRunTest(java.lang.String, java.lang.String) ((null):-2)
01-26 15:11:30.210 6403 6507 F art : art/runtime/thread.cc:1657] at void com.example.test.TestMain.run() ((null):-1)
01-26 15:11:30.210 6403 6507 F art : art/runtime/thread.cc:1657] at void java.lang.Thread.run() (Thread.java:761)
01-26 15:11:30.210 6403 6507 F art : art/runtime/thread.cc:1657]
01-26 15:11:30.253 6403 6507 F art : art/runtime/runtime.cc:422] Runtime aborting...
01-26 15:11:30.253 6403 6507 F art : art/runtime/runtime.cc:422] Aborting thread:
01-26 15:11:30.253 6403 6507 F art : art/runtime/runtime.cc:422] "TestThread" prio=5 tid=14 Runnable
... lots of lines indicating a crash follow ...
此行为是否违反JNI规范,JNI规范明确指出如果找不到指定的方法,GetMethodID()
应该返回NULL
?
如果这确实是预期的行为,是否还有其他方法可以从C代码中找出Java方法是否存在?
答案 0 :(得分:1)
GetMethodID
返回NULL
。但是,它还会引发NoSuchMethodError
异常:
投掷:
NoSuchMethodError
:如果找不到指定的方法。
在JNI函数抛出未决异常时,调用most JNIEnv
methods-或尝试返回Java * 是错误的。请注意,这些异常不是C ++异常,因此即使在C ++中,也无法使用try
/ catch
来捕获它们。而且在C语言中,这显然不是一个选择。
JNIEnv
为您提供了以下方法来处理这些异常:
ExceptionOccurred
ExceptionDescribe
ExceptionClear
因此,在这种情况下,您可能并不十分在意该异常,因此以下代码足以处理该异常:
if ((*env)->ExceptionCheck(env)) {
(*env)->ExceptionClear(env);
}
在每次可能引发异常的JNI调用之后,都需要进行这类检查。
* 除非您在Java方面遇到了麻烦。