cocos2d-x 3.10热更强制退出无法继续下载+IOS热更资源有空格热更出错的Bug解决方法

来源:互联网 发布:程序员最想去的公司 编辑:程序博客网 时间:2024/05/03 21:39

1、Cocos2dx热更新因为文件名含有空格,ios下载失败bug修改

问题描述:

  项目中偶尔遇到美术图片命名时不规范,导致图片名字含有空格。导致ios热更新时,遇到下载失败。

解决方案:

1.从新改名字(以后命名一定要规范)

2.空格转义 解决下载失败问题

url

web 开发中通过问号(?)方式在浏览器地址栏中传值时。浏览器是通过“&”来区分问号后的参数个数的。 如果出现传值参数中带有“&”时,在接受页面就会出现错误,类似如下请求路径:/next.jsp?param1=hendhs89&furej & param2=sss
参数param1中含有转义字符“&” ,这样会导致被请求页的参数接收错误。
在传值前 通过 java.net.URLEncoder.encode(param1) 编码处理后,可将转义字符转为16进制;
1. + URL 中+号表示空格 %2B
2. 空格 URL中的空格可以用+号或者编码 %20
3. / 分隔目录和子目录 %2F
4. ? 分隔实际的 URL 和参数 %3F
5. % 指定特殊字符 %25
6. # 表示书签 %23
7. & URL中指定的参数间的分隔符%26
8. = URL中指定参数的值 %3D
9. ! URL中指定参数的值 %2
 

具体解决方案

1、AssetsManagerEx::startUpdate()中,拼接地址时,将空格转义

复制代码
void AssetsManagerEx::startUpdate(){    if (_updateState != State::NEED_UPDATE)        return;    _updateState = State::UPDATING;    // Clean up before update    _failedUnits.clear();    _downloadUnits.clear();    _compressedFiles.clear();    _totalWaitToDownload = _totalToDownload = 0;    _percent = _percentByFile = _sizeCollected = _totalSize = 0;    _downloadedSize.clear();    _totalEnabled = false;        // Temporary manifest exists, resuming previous download    if (_tempManifest->isLoaded() && _tempManifest->versionEquals(_remoteManifest))    {        _tempManifest->genResumeAssetsList(&_downloadUnits);        _totalWaitToDownload = _totalToDownload = (int)_downloadUnits.size();        this->batchDownload();                std::string msg = StringUtils::format("Resuming from previous unfinished update, %d files remains to be finished.", _totalToDownload);        dispatchUpdateEvent(EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "", msg);    }    // Check difference    else    {        // Temporary manifest not exists or out of date,        // it will be used to register the download states of each asset,        // in this case, it equals remote manifest.        _tempManifest->release();        _tempManifest = _remoteManifest;                std::unordered_map<std::string, Manifest::AssetDiff> diff_map = _localManifest->genDiff(_remoteManifest);        if (diff_map.size() == 0)        {            updateSucceed();        }        else        {            // Generate download units for all assets that need to be updated or added            std::string packageUrl = _remoteManifest->getPackageUrl();            for (auto it = diff_map.begin(); it != diff_map.end(); ++it)            {                Manifest::AssetDiff diff = it->second;                if (diff.type == Manifest::DiffType::DELETED)                {                    _fileUtils->removeFile(_storagePath + diff.asset.path);                }                else                {                    std::string path = diff.asset.path;                    // Create path                    _fileUtils->createDirectory(basename(_storagePath + path));                    DownloadUnit unit;                    unit.customId = it->first;                                        std::string str(path),s2(" "),s3("%20");                    std::string::size_type pos=0;                    std::string::size_type a=s2.size();                    std::string::size_type b=s3.size();                    while((pos=str.find(s2,pos))!=std::string::npos)                    {                        str.replace(pos,a,s3);                        pos+=b;                    }                    unit.srcUrl = packageUrl + str;                    unit.storagePath = _storagePath + path;                    _downloadUnits.emplace(unit.customId, unit);                }            }            // Set other assets' downloadState to SUCCESSED            auto &assets = _remoteManifest->getAssets();            for (auto it = assets.cbegin(); it != assets.cend(); ++it)            {                const std::string &key = it->first;                auto diffIt = diff_map.find(key);                if (diffIt == diff_map.end())                {                    _tempManifest->setAssetDownloadState(key, Manifest::DownloadState::SUCCESSED);                }            }            _totalWaitToDownload = _totalToDownload = (int)_downloadUnits.size();            this->batchDownload();                        std::string msg = StringUtils::format("Start to update %d files from remote package.", _totalToDownload);            dispatchUpdateEvent(EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "", msg);        }    }}
复制代码

2、Manifest.cpp

复制代码
void Manifest::genResumeAssetsList(DownloadUnits *units) const{    for (auto it = _assets.begin(); it != _assets.end(); ++it)    {        Asset asset = it->second;                if (asset.downloadState != DownloadState::SUCCESSED)        {            DownloadUnit unit;            unit.customId = it->first;            std::string str(asset.path),s2(" "),s3("%20");            std::string::size_type pos=0;            std::string::size_type a=s2.size();            std::string::size_type b=s3.size();            while((pos=str.find(s2,pos))!=std::string::npos)            {                str.replace(pos,a,s3);                pos+=b;            }            unit.srcUrl = _packageUrl + str;            unit.storagePath = _manifestRoot + asset.path;            units->emplace(unit.customId, unit);        }    }}
复制代码

2、Cocos2dx热更新因为文件名含有空格,ios下载失败bug修改

问题描述:

AsstsManagerEx: project.manifest may be downloaded twice。

project.manifest下载两次 ,导致热更新失败。打印log提示 解析project.manifest失败。

解决方案:

Cocos 3.14版本 自己解决了这个问题,根据就该日志 更新下载器。

 

3、更新过程强制退出,导致不能缓存下载。下载失败之后,不对比MD5所有文件都下载bug。

新版本不知道有没有。这个对应版本是 3.11

解决思路 。

下载器一开始先判断有没有缓存文件,有缓存文件的话,直接读取缓存文件。由于上一次强退没有及时将下载进度写到缓存文件中

所以所有文件的状态都是1.这里由于是临时清单文件,没有做MD5对比。所有所有文件都被添加到下载清单,出现bug

如果正常出错,没有强退。下载器会正常调用,写临时清单,这个不会有bug。

复制代码
复制代码
void AssetsManagerEx::startUpdate(){    if (_updateState != State::NEED_UPDATE)        return;    _updateState = State::UPDATING;    // Clean up before update    _failedUnits.clear();    _downloadUnits.clear();    _compressedFiles.clear();    _totalWaitToDownload = _totalToDownload = 0;    _percent = _percentByFile = _sizeCollected = _totalSize = 0;    _downloadedSize.clear();    _totalEnabled = false;        // Temporary manifest exists, resuming previous download    if (_tempManifest->isLoaded() && _tempManifest->versionEquals(_remoteManifest))    {        std::unordered_map<std::string, Manifest::AssetDiff> diff_map = _localManifest->genDiff(_remoteManifest);        if (diff_map.size() == 0)        {            updateSucceed();        }        else        {            // Set other assets' downloadState to SUCCESSED            auto &assets = _remoteManifest->getAssets();            for (auto it = assets.cbegin(); it != assets.cend(); ++it)            {                const std::string &key = it->first;                auto diffIt = diff_map.find(key);                if (diffIt == diff_map.end())                {                    _tempManifest->setAssetDownloadState(key, Manifest::DownloadState::SUCCESSED);                }            }            _tempManifest->genResumeAssetsList(&_downloadUnits);            _totalWaitToDownload = _totalToDownload = (int)_downloadUnits.size();            this->batchDownload();                        std::string msg = StringUtils::format("Resuming from previous unfinished update, %d files remains to be finished.", _totalToDownload);            dispatchUpdateEvent(EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "", msg);        }    }    // Check difference    else

阅读全文
0 0
原创粉丝点击