1.诱因
近期,项目接入了Bugly, 上报了一些平常测试不出来,或者很难重现的bug,这类bug非常难排查。原因有二,第一,问题无法重现,第二,修改了无法立即验证结果。有一个问题困恼了我很久,就是一直报这块的代码出错。(dispatchEvent报错)
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h) { auto director = cocos2d::Director::getInstance(); auto glview = director->getOpenGLView(); if (!glview) { glview = cocos2d::GLViewImpl::create("Android app"); glview->setFrameSize(w, h); director->setOpenGLView(glview); //cocos_android_app_init(env, thiz); cocos2d::Application::getInstance()->run(); } else { cocos2d::GL::invalidateStateCache(); cocos2d::GLProgramCache::getInstance()->reloadDefaultGLPrograms(); cocos2d::DrawPrimitives::init(); cocos2d::VolatileTextureMgr::reloadAllTextures(); cocos2d::EventCustom recreatedEvent(EVENT_RENDERER_RECREATED); director->getEventDispatcher()->dispatchEvent(&recreatedEvent); director->setGLDefaultValues(); } }
2.分析问题
这个一看就是为了防止安卓后台返回资源重建,就去查找所有有做资源重建的类,这一看就找到了以下代码。
bool DrawNode::init() { _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED; setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR)); ensureCapacity(512); ensureCapacityGLPoint(64); ensureCapacityGLLine(256); if (Configuration::getInstance()->supportsShareableVAO()) { glGenVertexArrays(1, &_vao); GL::bindVAO(_vao); } glGenBuffers(1, &_vbo); glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(V2F_C4B_T2F)* _bufferCapacity, _buffer, GL_STREAM_DRAW); // vertex glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, vertices)); // color glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, colors)); // texcood glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORD); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, texCoords)); if (Configuration::getInstance()->supportsShareableVAO()) { glGenVertexArrays(1, &_vaoGLLine); GL::bindVAO(_vaoGLLine); } glGenBuffers(1, &_vboGLLine); glBindBuffer(GL_ARRAY_BUFFER, _vboGLLine); glBufferData(GL_ARRAY_BUFFER, sizeof(V2F_C4B_T2F)*_bufferCapacityGLLine, _bufferGLLine, GL_STREAM_DRAW); // vertex glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, vertices)); // color glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, colors)); // texcood glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORD); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, texCoords)); if (Configuration::getInstance()->supportsShareableVAO()) { glGenVertexArrays(1, &_vaoGLPoint); GL::bindVAO(_vaoGLPoint); } glGenBuffers(1, &_vboGLPoint); glBindBuffer(GL_ARRAY_BUFFER, _vboGLPoint); glBufferData(GL_ARRAY_BUFFER, sizeof(V2F_C4B_T2F)*_bufferCapacityGLPoint, _bufferGLPoint, GL_STREAM_DRAW); // vertex glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, vertices)); // color glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, colors)); // texcood glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORD); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, texCoords)); glBindBuffer(GL_ARRAY_BUFFER, 0); if (Configuration::getInstance()->supportsShareableVAO()) { GL::bindVAO(0); } CHECK_GL_ERROR_DEBUG(); _dirty = true; _dirtyGLLine = true; _dirtyGLPoint = true; #if CC_ENABLE_CACHE_TEXTURE_DATA // Need to listen the event only when not use batchnode, because it will use VBO auto listener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom* event){ /** listen the event that renderer was recreated on Android */ this->init();//此处会一直添加监听,重复添加 }); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); #endif return true; }