java - 为什么 GetMethodID() 对不存在的方法不返回 NULL?

标签 java android c android-ndk java-native-interface

所以关于 GetMethodID() 的文档说的是:

Returns a method ID, or NULL if the specified method cannot be found.

但是,在 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 规范,该规范明确规定,如果找不到指定的方法,GetMethodID() 应返回 NULL

如果这确实是预期的行为,是否有其他方法可以从 C 代码中找出 Java 方法是否存在?

最佳答案

GetMethodID 在这种情况下,确实返回NULL。但是,它也会引发 NoSuchMethodError 异常:

THROWS:
NoSuchMethodError: if the specified method cannot be found.

调用 most JNIEnv methods 时出错- 或者尝试返回到 Java* - 当 JNI 函数抛出未决异常时。请注意,这些异常不是 C++ 异常,因此即使在 C++ 中,也不能使用 try/catch 来捕获它们。而在 C 语言中,这显然不是一个选择。

JNIEnv 为您提供了以下方法来处理这些异常:

ExceptionOccurred
ExceptionDescribe
ExceptionClear

因此,在这种特殊情况下,您可能并不真正关心异常,以下代码足以处理它:

if ((*env)->ExceptionCheck(env)) {
    (*env)->ExceptionClear(env);
}

在每次可能引发异常的 JNI 调用之后都需要进行此类检查。


*除非你在Java端捕获异常。

关于java - 为什么 GetMethodID() 对不存在的方法不返回 NULL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54379212/

相关文章:

java - Eclipse RCP : move createPartControl into background

Android找不到应用程序的mainactivity

c - 迭代矩阵中的不同对角线并在 C 中建立其起点和终点?

java - 在开始路由之前交叉检查camel ftp/sftp身份验证

java - Android 版 Youtube API - 创建多个缩略图

android - 将旧的 Android 项目导入 Eclipse 时缺少 AndroidManifest.xml

android - 在运行时推送通知(GCM)权限?

c - 为什么这个 print 语句可以阻止 C 程序崩溃?

c - 如何创建具有未定义类型的独立链接列表标题

java - 针对 Poodle (SSL3) 漏洞,我应该在 Tomcat 中删除哪些 SSL 密码