Android 开发系列(4) - JNIEnv::FindClass 的问题
在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
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。