在native代码回调 java端代码,使用 JNIEnv::FindClass 函数。
当FindClass的类实际不存在时,可能会影响Env内部的状态,在后续对JNIEnv的其他调用过程中出现 崩溃。
下面为调用的代码: (jobject xmlDoc 为 java端创建的 org.w3c.Dom.Document 对象)
int TestCall(JNIEnv *pEnv, jobject xmlDoc)
{
XmlDocument doc(pEnv, xmlDoc);
jclass cls_Temp = pEnv->FindClass("com/xyz/samples/myclass"); // 这个类不存在
jobject rootElement = doc.getDocumentElement(); // 这个函数正常
if( rootElement == 0 ){
LOGE("doc Root error");
return 0;
}
jstring rootName = doc.Node_getNodeName(rootElement); // 这个函数崩溃
//... 其他代码
}
XmlDocument::XmlDocument(JNIEnv *pEnv, jobject doc) {
m_Doc = pEnv->NewGlobalRef(doc);
m_pEnv = pEnv;
}
jobject XmlDocument::getDocumentElement()
{
jclass cls = m_pEnv->GetObjectClass(m_Doc);
jmethodID id = m_pEnv->GetMethodID(cls, "getDocumentElement", "()Lorg/w3c/dom/Element;");
return m_pEnv->CallObjectMethod(m_Doc, id);
}
jstring XmlDocument::Node_getNodeName(jobject node)
{
//("org/w3c/dom/Node");
// jclass cls = m_pEnv->FindClass("org/w3c/dom/Node");
// if( cls == 0 ){
// LOGE("Node_getNodeName: cls empty");
// return 0;
// }
jclass cls = m_pEnv->GetObjectClass(node);
jmethodID id = m_pEnv->GetMethodID(cls, "getNodeName", "()Ljava/lang/String;");
return (jstring)m_pEnv->CallObjectMethod(node, id);
}
上面最后一个函数在 GetObjectClass中崩溃。
如果改为其中注释掉的代码代替 GetObjectClass ,则 cls == 0 不成立,在后续的GetMethodID处崩溃。
在最上面的TestCall函数中,去掉那个 对不存在类的FindClass 调用后,则函数均能正常工作。
疑似 FindClass 有Bug!!(以后有机会翻翻源码看看)
使用的版本为:Android SDK 23, targetSDKVersion 19。 JNI_OnLoader 返回版本为 JNI_VERSION_1_6