在我的C ++应用程序类JNIXMLDocument
中进行了一些JAVA方法调用。在JNIXMLDocument
类的构造函数中,我附加当前线程并将其设置为我的类成员JNIEnv* m_JavaEnv
,然后在所有方法中使用它。同样在构造函数中,我试图找到我的JAVA类com/fido/android/framework/service/XMLDOMDocument
并将其设置为类成员m_XMLDocumentClass
,并从类中获取该类对象并将其设置为类成员m_XMLDocumentObject
。 / p>
class JNIXMLDocument
{
/* Constructor **/
JNIXMLDocument()
{
/* Get JNI right version and set it. **/
jint interface_id = JNI_VERSION_1_2;
#ifdef JNI_VERSION_1_2
interface_id = JNI_VERSION_1_2;
#else
interface_id = JNI_VERSION_1_1;
#endif
/* Trying to attach current thread. **/
int res = g_JavaVirtualMachine->GetEnv(&m_JavaEnv, interface_id);
if (res == JNI_EDETACHED || res == JNI_EVERSION) {
res = g_JavaVirtualMachine->AttachCurrentThread(&m_JavaEnv, NULL);
}
/* Get Class from Java **/
m_XMLDocumentClass = m_JavaEnv->FindClass("com/fido/android/framework/service/XMLDOMDocument");
if (m_XMLDocumentClass != NULL) {
/* Call java class constructor. **/
jmethodID constructor = m_JavaEnv->GetMethodID(m_XMLDocumentClass , "<init>", "()V");
m_XMLDocumentObject = m_JavaEnv->NewObject(m_XMLDocumentClass , constructor);
}
}
bool Initialize()
{
jmethodID method = m_JavaEnv->GetMethodID(m_XMLDocumentClass, "Initialize", "()Lorg/w3c/dom/Document;");
jobject document = m_JavaEnv->CallObjectMethod(m_XMLDocumentObject , method);
}
private:
JNIEnv* m_JavaEnv;
jclass m_XMLDocumentClass;
jobject m_XMLDocumentObject;
};
class JNIXMLDocument
{
/* Constructor **/
JNIXMLDocument()
{
/* Get JNI right version and set it. **/
jint interface_id = JNI_VERSION_1_2;
#ifdef JNI_VERSION_1_2
interface_id = JNI_VERSION_1_2;
#else
interface_id = JNI_VERSION_1_1;
#endif
JNIEnv* env;
/* Trying to attach current thread. **/
int res = g_JavaVirtualMachine->GetEnv(&env, interface_id);
if (res == JNI_EDETACHED || res == JNI_EVERSION) {
res = g_JavaVirtualMachine->AttachCurrentThread(&env, NULL);
}
/* Get Class from Java **/
jclass localClass = env->FindClass("com/fido/android/framework/service/XMLDOMDocument");
if (localClass != NULL) {
m_XMLDocumentClass = env->NewGlobalRef(localClass);
/* Call java class constructor. **/
jmethodID constructor = env->GetMethodID(localClass, "<init>", "()V");
jobject localObject = env->NewObject(m_XMLDocumentClass , constructor);
m_XMLDocumentObject = env->NewGlobalRef(localObject );
}
}
bool Initialize()
{
}
private:
jclass m_XMLDocumentClass;
jobject m_XMLDocumentObject;
};
JNIEnv* m_JavaEnv
)并在整个代码中使用它是正确的吗?jclass m_XMLDocumentClass
是否正确,而不是在所有方法中使用该变量?jobject m_XMLDocumentObject
在构造函数中设置m_JavaEnv->NewObject(m_XMLDocumentClass , constructor);
是否正确,或者我必须致电NewGlobalRef
。答案 0 :(得分:3)
在构造函数中设置一次JNI接口指针(JNIEnv * m_JavaEnv)并在整个代码中使用它是正确的吗?
没有。它是特定于线程的。这就是Attach / DetachCurrentThread的用途。唯一可行的方法是在同一个线程中构造和销毁C ++对象。
在构造函数中设置jclass m_XMLDocumentClass是否正确,而不是在所有方法中使用该变量?
没有。它是一个本地引用,它在返回时获取的JNI方法到期。您必须另存为全局或弱引用,除非仅在单个JNI方法中使用。
Is it right to set jobject m_XMLDocumentObject in the constructor in this way m_JavaEnv->NewObject(m_XMLDocumentClass , constructor);
否:见上文。
或者我必须打电话给NewGlobalRef。
是的,如上所述。
如果我的应用程序不在同一个线程中(使用多个线程),会出现什么问题?
主要是JVM崩溃。 JVM假定您遵循JNI规范中的所有规则。那样做。