Por lo que la documentación sobre GetMethodID () dice lo siguiente:
Devuelve un ID de método, o NULL si el método especificado no se puede encontrar.
En Android, sin embargo, esto no parece ser el caso debido a llamar GetMethodID()
con un nombre que no existe método siempre lanza una excepción grave y mata a todo el hilo. Considere este código:
jmethodID id = (*env)->GetMethodID(env, mActivityClass, "iDontExist", "()V");
Esto resulta en un accidente completo de hilos, y la siguiente salida en 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 ...
No es este el comportamiento de una violación de la especificación JNI que dice claramente que GetMethodID()
debe devolver NULL
si el método especificado no se puede encontrar?
Si esto es realmente la intención de comportamiento, ¿hay alguna otra manera de descubrir a partir del código C si existe un método Java?
GetMethodID
no volver NULL
en este caso. Sin embargo, también lanza una NoSuchMethodError
excepción:
Lanza:
NoSuchMethodError
: si el método especificado no se puede encontrar.
Es un error llamar a la mayoría de los JNIEnv
métodos - o tratar de volver a Java * - mientras que hay una excepción a la espera tirado por una función JNI. Tenga en cuenta que estas excepciones no son excepciones de C ++, por lo que incluso en C ++ no se puede usar try
/ catch
para capturarlos. Y en C que, obviamente, no puede ser una opción de todos modos.
El JNIEnv
te ofrece los siguientes métodos para manejar estas excepciones:
ExceptionOccurred
ExceptionDescribe
ExceptionClear
Así que en este caso particular en que es probable que no realmente se preocupan por la excepción, el siguiente código sería suficiente para manejarlo:
if ((*env)->ExceptionCheck(env)) {
(*env)->ExceptionClear(env);
}
Este tipo de necesidades controles que deben realizarse después de cada llamada JNI que podría lanzar una excepción.
* A menos que se captura la excepcion en el lado de Java.