JNI NewStringUTF 调用挂起异常 'java.lang.NoSuchMethodError'
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33674631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JNI NewStringUTF called with pending exception 'java.lang.NoSuchMethodError'
提问by ali kiani
I don't know why exception is being thrown when I call native method.
我不知道为什么在调用本机方法时会抛出异常。
Native code :
本机代码:
JNIEXPORT jstring JNICALL Java_org_amk_lockscreen_JNIActivity_getPackege(JNIEnv *env,jclass cls,jobject context){
jclass Context_class = (*env).FindClass("android/content/Context");
jmethodID midGetPackageName = (*env).GetMethodID(Context_class, "getPackageName", "(V)Ljava/lang/String;");
if(midGetPackageName==0){
return (*env).NewStringUTF("Not Found Method");
}
else{
jobject packageName=(*env).CallObjectMethod( context, midGetPackageName);
return (jstring)packageName;
}
}
and my java code:
和我的Java代码:
public class JNIActivity extends Activity {
static {
System.loadLibrary("myjni"); // "myjni.dll" in Windows, "libmyjni.so" in Unixes
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_jni);
TextView txt = (TextView) findViewById(R.id.txtMessage);
try {
txt.setText(getPackege(getApplicationContext()));
} catch (Exception exp) {
txt.setText(exp.getMessage());
}
}
public native String getMessage();
public native String getPackege(Context con);
}
but when run this, it throws exception:
但是当运行这个时,它会抛出异常:
JNI DETECTED ERROR IN APPLICATION: JNI NewStringUTF called with pending exception 'java.lang.NoSuchMethodError' thrown in java.lang.String org.amk.lockscreen.JNIActivity.getPackege(android.content.Context):-2
in call to NewStringUTF
from java.lang.String org.amk.lockscreen.JNIActivity.getPackege(android.content.Context)
I have tested different method signature, like:
我测试了不同的方法签名,例如:
(Ljava/lang/Void;)Ljava/lang/String;
(V;)Ljava/lang/String;
but it throws exception again.
但它再次抛出异常。
Where I made a mistake?
我哪里做错了?
回答by JJF
GetMethodID is raising an exception. You are not checking to see if an exception was raised with env->ExceptionCheck(env) then clearing it with ExceptionClear() or returning immediately from the function so the JVM handles it. See the Oracle doc on getMethodId here: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html
GetMethodID 引发异常。您不会检查是否使用 env->ExceptionCheck(env) 引发异常,然后使用 ExceptionClear() 清除它或立即从函数返回以便 JVM 处理它。在此处查看有关 getMethodId 的 Oracle 文档:http: //docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html
For example (from http://www.ibm.com/developerworks/library/j-jni/:) findClass, GetStaticMethodID and CallStaticVoidMethod call all generate exceptions similar to GetMethodID.
例如(来自http://www.ibm.com/developerworks/library/j-jni/:) findClass、GetStaticMethodID 和 CallStaticVoidMethod 调用都会生成类似于 GetMethodID 的异常。
int val=1;
jmethodID method;
jclass cls;
cls = (*env)->FindClass(env, "com/ibm/example/TestClass");
if ((*env)->ExceptionCheck(env)) {
return ERR_FIND_CLASS_FAILED;
}
method = (*env)->GetStaticMethodID(env, cls, "setInfo", "(I)V");
if ((*env)->ExceptionCheck(env)) {
return ERR_GET_STATIC_METHOD_FAILED;
}
(*env)->CallStaticVoidMethod(env, cls, method,val);
if ((*env)->ExceptionCheck(env)) {
return ERR_CALL_STATIC_METHOD_FAILED;
}
回答by IgorGanapolsky
You method definition is wrong here:
你的方法定义在这里是错误的:
jmethodID midGetPackageName = (*env).GetMethodID(Context_class, "getPackageName", "(V)Ljava/lang/String;");
jmethodID midGetPackageName = (*env).GetMethodID(Context_class, "getPackageName", "(V)Ljava/lang/String;");
You simply cannot pass (V)in the parameter, as that means you are passing a void parameter, which doesn't make sense in Java. You need to figure out what parameter types are being passed to your java method (e.g. String), and what return type this method returns (e.g. void).
您根本无法在参数中传递(V),因为这意味着您正在传递一个 void 参数,这在 Java 中没有意义。您需要弄清楚传递给您的 java 方法的参数类型(例如String),以及该方法返回的返回类型(例如void)。
Hence, you probably meant to do something like this:
因此,您可能打算执行以下操作:
jmethodID midGetPackageName = (*env).GetMethodID(Context_class, "getPackageName", "Ljava/lang/String;(V)");
jmethodID midGetPackageName = (*env).GetMethodID(Context_class, "getPackageName", "Ljava/lang/String;(V)");