Cocos2d-x 3.9 AssetsManagerEx 实现热更新 BUG解决

    网上AssetsManagerEx 实现热更新的同类教程很多,这里我就不详细介绍了,基本上按照cocos2d-x的demo来做就行了,但有几个坑要个大家提醒一下.

    1.AssetsManagerEx的创建,第一个参数是当前的project.manifest文件路径,第二个是资源下载后的存放路径.更新后会下载的project.manifest与version.manifest文件放到 存放路径 !!!而且名字也是叫project.manifest与version.manifest,所以不建议改成其他的名字,给自己带来麻烦.具体路径可根据自己的项目配置进行修改

const auto fileUtils = FileUtils::getInstance();
const auto writablePath = fileUtils->getWritablePath();
if (fileUtils->isFileExist(writablePath + "Assets/project.manifest"))
{
	_AssetsManagerEx = AssetsManagerEx::create(writablePath + "Assets/project.manifest", writablePath + "Assets/");
}
else
{
	_AssetsManagerEx = AssetsManagerEx::create("project.manifest", writablePath + "Assets/");
}
_AssetsManagerEx->retain();

    2.更新进度

// 获得当前下载文件的下载百分比
int percent = event->getPercent();
// 获得总的下载百分比
int percentByFile = event->getPercentByFile();

    以上两个只是小坑,AssetsManagerEx现在是对比单个文件来下载,所以如果不对多个文件进行压缩,肯定会使第一次更新或跨N多个版本需要一次性下载大量的文件,比如我当前这个项目总共有2000多个,生成的json文件有7000多行.这时候你就会发现log中打印了 Can't open file:XXXX的信息.这是因为AssetsManagerEx会在一开始将所有需要下载的东西加入下载队列,而下载会为下载的文件创建一个.temp的文件,并且一直保持的打开,而同时打开的文件是有上限的,并且不同的操作系统上限也不同,比如windows是512个,所以我对源代码多处进行了修改,当打开到达上限之后,不在继续添加,而是下载完成前面一批之后再加入一批.

CCDownloader-curl.cpp   143 行

函数 bool init(const string& filename, const string& tempSuffix)

// open file
_fp = fopen(util->getSuitableFOpen(_tempFileName).c_str(), "ab");
if (nullptr == _fp)
{
    _errCode = DownloadTask::ERROR_FILE_OP_FAILED;
    _errCodeInternal = 0;
    _errDescription = "Can't open file:";
    _errDescription.append(_tempFileName);
	break;// 增加break 让init返回false
}
ret = true;

只增加了break;让打开失败返回false;

CCDownloader-curl.cpp 745行

函数 IDownloadTask *DownloaderCURL::createCoTask(std::shared_ptr<const DownloadTask>& task)

// 增加对返回值的判断
if (!coTask->init(task->storagePath, _impl->hints.tempFileNameSuffix))
{
	// 失败释放并返回空
	delete coTask;
	return nullptr;
}

本来是没有判断的 现在加上判断释放并返回nullptr

CCDownloader.cpp 174行

//task_->_coTask.reset(_impl->createCoTask(task));
// 创建下载任务
IDownloadTask* tempTask = _impl->createCoTask(task);
if (tempTask)
{
	task_->_coTask.reset(tempTask);
}
else
{
	return nullptr;
}

由于现在回返回nullptr,所以对返回值进行判断如果有还是和以前一样,没有返回nullptr

AssetsManagerEx.h  193行

void batchDownload();

// 加入下一批
void batchDownloadAgain();

//! The event of the current AssetsManagerEx in event dispatcher
    std::string _eventName;

通过调用batchDownloadAgain来下载下一批资源

AssetsManagerEx.h  243行

// 当前下载到哪
DownloadUnits::iterator _downloadIter;
    
// 再次开启下载需要到达的数量
int _downloadAgainNum;

增加两个成员变量记录下载状态

AssetsManagerEx.cpp  946行

// Reduce count only when unit found in _downloadUnits
_totalWaitToDownload--;
            
_percentByFile = 100 * (float)(_totalToDownload - _totalWaitToDownload) / _totalToDownload;
// 下载下一批
if (_totalToDownload - _totalWaitToDownload >= _downloadAgainNum)
{
	batchDownloadAgain();
}
// Notify progression event
dispatchUpdateEvent(EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION, "");

通过判断当前已经下载了的数量来确定是否要加入下一批

AssetsManagerEx.cpp  992行

函数 void AssetsManagerEx::batchDownload() 修改

void AssetsManagerEx::batchDownload()
{
	// 开始下载前初始化下载位置
	_downloadIter = _downloadUnits.begin();
	_downloadAgainNum = 0;
	batchDownloadAgain();
}

现在这个方法用来初始化 并开启一次下载

AssetsManagerEx.cpp  1006行

void AssetsManagerEx::batchDownloadAgain()
{
	for (; _downloadIter != _downloadUnits.end(); ++_downloadIter)
	{
		++_downloadAgainNum;
		DownloadUnit& unit = _downloadIter->second;
		// 判断下载任务创建是否失败
		if (_downloader->createDownloadFileTask(unit.srcUrl, unit.storagePath, unit.customId) == nullptr)
		{
			--_downloadAgainNum;
			// fopen打开文件有限制 创建任务失败
			break;
		}
	}
}

增加对batchDownloadAgain的实现

 

 

C++实现的委托,如果有兴趣的话可以一起讨论一下哈

https://git.oschina.net/.cgy.com/Delegate

转载于:https://my.oschina.net/578467246/blog/806984

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值