出现的几率比较低,在小米手机出现的次数比较多。安卓手机,开启游戏,游戏不响应所有的点击事件和KeyPressed事件。游戏肯定没有crash,首页的动画播放和背景音效都正常。
经过排查发现问题出现在CCEventDispatcher.cpp文件中,_inDispatch计数,出现紊乱,变成2,所有的listener都无法进入队列,所以无法将事件传递下去。
出现这个问题是因为 EventDispatcher::dispatchEvent
不应该在非Cocos线程中调用。经过全局搜索,发现在CCFileUtils-android.cpp中
FileUtils::Status FileUtilsAndroid::getContents(const std::string& filename, ResizableBuffer* buffer)
{
Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(EVENT_BEFORE_READ_FILE);
static const std::string apkprefix("assets/");
if (filename.empty())
return FileUtils::Status::NotExists;
string fullPath = fullPathForFilename(filename);
if (fullPath[0] == '/')
return FileUtils::getContents(fullPath, buffer);
string relativePath = string();
size_t position = fullPath.find(apkprefix);
if (0 == position) {
// "assets/" is at the beginning of the path and we don't want it
relativePath += fullPath.substr(apkprefix.size());
} else {
relativePath = fullPath;
}
if (obbfile)
{
if (obbfile->getFileData(relativePath, buffer))
return FileUtils::Status::OK;
}
if (nullptr == assetmanager) {
LOGD("... FileUtilsAndroid::assetmanager is nullptr");
return FileUtils::Status::NotInitialized;
}
AAsset* asset = AAssetManager_open(assetmanager, relativePath.data(), AASSET_MODE_UNKNOWN);
if (nullptr == asset) {
LOGD("asset is nullptr");
return FileUtils::Status::OpenFailed;
}
auto size = AAsset_getLength(asset);
buffer->resize(size);
int readsize = AAsset_read(asset, buffer->buffer(), size);
AAsset_close(asset);
if (readsize < size) {
if (readsize >= 0)
buffer->resize(readsize);
return FileUtils::Status::ReadFailed;
}
return FileUtils::Status::OK;
}