这是我在monodroid应用程序中通过JNIEnv访问的Java类
package mypackage;
import android.util.Log;
public class JavaScriptInterface {
public String submitAns = "";
// The JNI in the original question uses a default constructor.
// Either provide one explicitly or use the implicit one...
public JavaScriptInterface()
{
}
public String getSelctd()
{
return submitAns;
}
}
我可以通过以下语句实例化该类:
Java.Lang.Object jclassWrp_;
IntPtr JavaScriptInterface_Class = JNIEnv.FindClass("mypackage.JavaScriptInterface");
IntPtr JavaScriptInterface_ctor = JNIEnv.GetMethodID(JavaScriptInterface_Class, "<init>", "()V"); //(Landroid/context/Context;)V
IntPtr jsInterfaceinstance_ = JNIEnv.NewObject(JavaScriptInterface_Class, JavaScriptInterface_ctor);
jclassWrp_ = new Java.Lang.Object(jsInterfaceinstance_, JniHandleOwnership.TransferGlobalRef);
但是当我尝试创建对象以访问 getSelctd()方法时:
IntPtr ipApid = JNIEnv.GetMethodID(jclassWrp_, "getSelctd", "()Ljava/lang/String;");
抛出NoSuchMethodExist异常...... 请告诉我,我是以正确的方式做到这一点以及我在这里缺少的......
答案 0 :(得分:1)
我可以通过以下语句实例化该类:
Java.Lang.Object jclassWrp_;
IntPtr JavaScriptInterface_Class = JNIEnv.FindClass("mypackage.JavaScriptInterface");
JNI使用应该使用JNI约定,因此mypackage/JavaScriptInterface
(注意/
而不是.
)。
IntPtr JavaScriptInterface_ctor = JNIEnv.GetMethodID(JavaScriptInterface_Class, "<init>", "()V");
IntPtr jsInterfaceinstance_ = JNIEnv.NewObject(JavaScriptInterface_Class, JavaScriptInterface_ctor);
jclassWrp_ = new Java.Lang.Object(jsInterfaceinstance_, JniHandleOwnership.TransferGlobalRef);
JNIEnv.NewObject()
会返回本地参考,而不是全局参考,因此您需要JniHandleOwnership.TransferLocalRef
。
但是当我尝试创建访问getSelctd()方法的对象时:
IntPtr ipApid = JNIEnv.GetMethodID(jclassWrp_, "getSelctd", "()Ljava/lang/String;");
JNIEnv.GetMethodID()
采用类句柄,而不是实例。首先,上面不应该编译(Java.Lang.Object
!= IntPtr
)。其次,jclassWrp
包含mypackage.JavaScriptInterface
实例,而不是mypackage.JavaScriptInterface
类实例。
相反,请执行:
IntPtr ipApid = JNIEnv.GetMethodID(JavaScriptInterface_Class, "getSelctd", "()Ljava/lang/String;");
最后,当你不再需要时,不要忘记JNIEnv.DeleteGlobalRef(JavaScriptInterface_Class)
,否则你会泄漏gref。
完整代码:
// FindClass() returns a gref; must be freed (see below)
IntPtr JavaScriptInterface_Class = JNIEnv.FindClass("mypackage/JavaScriptInterface");
// MethodIDs do not need to be freed
IntPtr JavaScriptInterface_ctor = JNIEnv.GetMethodID(JavaScriptInterface_Class,
"<init>", "()V");
IntPtr JavaScriptInterface_getSelctd = JNIEnv.GetMethodID(JavaScriptInterface_Class,
"getSelctd", "()Ljava/lang/String;");
// JNIEnv.NewObject() & JNIEnv.CallObjectMethod() return lrefs; freed below
IntPtr lrefInstance = JNIEnv.NewObject(JavaScriptInterface_Class,
JavaScriptInterface_ctor);
IntPtr lrefSelectd = JNIEnv.CallObjectMethod(jsInterfaceinstance_, ipApid);
// JniHandleOwnership.TransferLocalRef causes lrefSelectd to be released for us
string selected = JNIEnv.GetString(lrefSelectd, JniHandleOwnership.TransferLocalRef);
// Resource cleanup
JNIEnv.DeleteLocalRef(lrefInstance);
JNIEnv.DeleteGlobalRef(JavaScriptInterface_Class);