1.7下 热更结束后 调用重启,再走检测更新, new jsb.AssetsManager(this.manifestUrl, storagePath); 会调用loadLocalManifest();
这个方法下 先加载本地的project,manifest, 然后自己和自己比较,判断版本相同后 然后 自己把自己刚下载的资源给删了,
导致下次进入,依然要重新下载
版本相同的话,应该是这个事件jsb.EventAssetsManager.ALREADY_UP_TO_DATE,打印Already up to date with the latest remote version,为什么会删除刚下载的资源呢?删除的逻辑是你自己新增的么?
还没到真正的版本检测, new jsb.AssetsManager(this.manifestUrl, storagePath),这个方法下就删除了,引擎里删除的
loadLocalManifest();
if (_localManifest->isLoaded())
{
// Compare with cached manifest to determine which one to use
if (cachedManifest)
{
bool localNewer = _localManifest->versionGreater(cachedManifest, _versionCompareHandle);
if (localNewer)
{
// Recreate storage, to empty the content
_fileUtils->removeDirectory(_storagePath);
_fileUtils->createDirectory(_storagePath);
CC_SAFE_RELEASE(cachedManifest);
}
else
{
CC_SAFE_RELEASE(_localManifest);
_localManifest = cachedManifest;
}
}
prepareLocalManifest();
}
你用最新的panda写的hotupdate脚本应该不会有这种问题的,可以先运行下官方的例子
用的就是git上下的例子 tutorial-hot-update
测试发现是 调用 cc.game.restart(); 后 游戏重启 自动走了 AssetsManagerEx::AssetsManagerEx(const std::string& manifestUrl, const std::string& storagePath) ,manifestUrl 带了地址,然后删掉了manifestUrl的目录,但是不知道为什么会自动调用这个方法
cc.game.restart(); 删除 手动重启 之后 热更新就会正常
你修改了hotupdate脚本么?可以把全部的热更脚本贴出来么?
cc.Class({
extends: cc.Component,
properties: {
m_label_ResVersion: cc.Label,
m_label_updateTips: cc.Label,
manifestUrl: {
default: null,
url : cc.RawAsset
},
_updating : false,
_needUpdate: false,
},
//检查更新回调函数
checkCb: function (event) {
switch (event.getEventCode()) {
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
cc.log("未发现本地配置文件");
this.m_label_updateTips.string = "未发现本地配置文件";
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
cc.log("下载配置文件失败");
this.m_label_updateTips.string = "下载配置文件失败";
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
cc.log("已是最新版本");
this.m_label_updateTips.string = "当前为最新版本";
GlobalEventManager.getInstance().emitEvent(window.LocalMessage, { tag: window.LocalMsgType.UPDATE_NOT_MESSAGE });
break;
case jsb.EventAssetsManager.NEW_VERSION_FOUND:
cc.log("发现版本需要更新");
this._needUpdate = true;
this.m_label_updateTips.string = "发现版本需要更新";
break;
default:
return;
}
LoadingView.dismiss();
cc.eventManager.removeListener(this._checkListener);
this._checkListener = null;
this._updating = false;
if (this._needUpdate) {
GlobalEventManager.getInstance().emitEvent(window.LocalMessage, { tag: window.LocalMsgType.UPDATE_NEED_MESSAGE });
cc.log("需要更新");
this.hotUpdate();
}
},
//更新回调函数
updateCb: function (event) {
var needRestart = false;
var failed = false;
switch (event.getEventCode()) {
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
cc.log('No local manifest file found, hot update skipped.');
failed = true;
break;
case jsb.EventAssetsManager.UPDATE_PROGRESSION:
var percent = event.getPercent();
var percentByFile = event.getPercentByFile();
cc.log("updateCb1-----percent" + percent + "percentByFile" + percentByFile);
var msg = event.getMessage();
if (msg) {
cc.log("updateCb-----", msg);
}
this.m_label_updateTips.string = "更新进度:" + (percent * 100).toFixed(0) + "%";
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
cc.log('Fail to download manifest file, hot update skipped.');
failed = true;
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
cc.log('Already up to date with the latest remote version.');
failed = true;
break;
case jsb.EventAssetsManager.UPDATE_FINISHED:
cc.log('更新完成 ' + event.getMessage());
needRestart = true;
break;
case jsb.EventAssetsManager.UPDATE_FAILED:
cc.log('更新失败 ' + event.getMessage());
this._failCount++;
if (this._failCount < 5) {
this._am.downloadFailedAssets();
}
else {
cc.log('Reach maximum fail count, exit update process');
this._failCount = 0;
failed = true;
ToastView.show("数据更新失败");
}
break;
case jsb.EventAssetsManager.ERROR_UPDATING:
cc.log('更新错误: ' + event.getAssetId() + ', ' + event.getMessage());
break;
case jsb.EventAssetsManager.ERROR_DECOMPRESS:
cc.log(event.getMessage());
break;
default:
break;
}
if (failed) {
cc.eventManager.removeListener(this._updateListener);
this._updateListener = null;
this._updating = false;
}
if (needRestart) {
cc.eventManager.removeListener(this._updateListener);
this._updateListener = null;
var searchPaths = jsb.fileUtils.getSearchPaths();
var newPaths = this._am.getLocalManifest().getSearchPaths();
console.log(JSON.stringify(newPaths));
Array.prototype.unshift(searchPaths, newPaths);
cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
cc.log("--------------HotUpdateSearchPaths----------------" + JSON.stringify(searchPaths));
jsb.fileUtils.setSearchPaths(searchPaths);
cc.game.restart();
cc.log("资源更热完成---重启游戏");
}
},
hotUpdate: function () {
if (this._am && !this._updating) {
this._updateListener = new jsb.EventListenerAssetsManager(this._am, this.updateCb.bind(this));
cc.eventManager.addListener(this._updateListener, 1);
if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
this._am.loadLocalManifest(this.manifestUrl);
}
this._failCount = 0;
this._am.update();
this._updating = true;
LoadingView.dismiss();
}
},
onLoad () {
// GameSystem.getInstance().initConfig();
},
start () {
if (!cc.sys.isNative) {
cc.log("非原生版本不调用热更新");
GlobalEventManager.getInstance().emitEvent(window.LocalMessage, { tag: window.LocalMsgType.UPDATE_NOT_MESSAGE });
return;
}
let storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'project-remote-asset');
let remoteUrl = storagePath + "/project.manifest";
let fullPath = "";
if (jsb.fileUtils.isFileExist(remoteUrl)) {
fullPath = remoteUrl;
cc.log("有下载配置文件");
}
else {
fullPath = cc.url.raw("resources/project.manifest");
cc.log("没有下载配置文件,使用本地配置");
}
cc.log("manifestUrl =" + this.manifestUrl);
var self = this;
cc.loader.load(fullPath, function (error, data) {
if (error) {
cc.log("error : " + error);
return;
}
self.m_label_ResVersion.string = "资源版本:v" + JSON.parse(data).version;
cc.log("资源版本:v" + JSON.parse(data).version)
});
cc.log("检测更新");
this.m_label_updateTips.string = "检测更新";
this._storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'project-remote-asset');
cc.log('----------------hotUpdate---------Storage path for remote asset : ' + this._storagePath);
this.versionCompareHandle = function (versionA, versionB) {
cc.log("JS Custom Version Compare: version A is " + versionA + ', version B is ' + versionB);
var vA = versionA.split('.');
var vB = versionB.split('.');
for (var i = 0; i < vA.length; ++i) {
var a = parseInt(vA[i]);
var b = parseInt(vB[i] || 0);
if (a === b) {
continue;
}
else {
return a - b;
}
}
if (vB.length > vA.length) {
return -1;
}
else {
return 0;
}
};
this._am = new jsb.AssetsManager("", this._storagePath, this.versionCompareHandle);
if (!cc.sys.ENABLE_GC_FOR_NATIVE_OBJECTS) {
this._am.retain();
}
this._am.setVerifyCallback(function (path, asset) {
// When asset is compressed, we don't need to check its md5, because zip file have been deleted.
var compressed = asset.compressed;
// Retrieve the correct md5 value.
var expectedMD5 = asset.md5;
// asset.path is relative path and path is absolute.
var relativePath = asset.path;
// The size of asset file, but this value could be absent.
var size = asset.size;
if (compressed) {
// panel.info.string = "Verification passed : " + relativePath;
return true;
}
else {
// panel.info.string = "Verification passed : " + relativePath + ' (' + expectedMD5 + ')';
return true;
}
});
if (cc.sys.os === cc.sys.OS_ANDROID) {
this._am.setMaxConcurrentTask(2);
}
this.checkUpdate();
// this.hotUpdate();
},
checkUpdate: function () {
if (this._updating) {
return;
}
cc.log("this._am.getState() === jsb.AssetsManager.State.UNINITED=" + this._am.getState() === jsb.AssetsManager.State.UNINITED);
if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
this._am.loadLocalManifest(this.manifestUrl);
}
if (!this._am.getLocalManifest() || !this._am.getLocalManifest().isLoaded()) {
this.m_label_updateTips.string = 'Failed to load local manifest ...';
return;
}
this._checkListener = new jsb.EventListenerAssetsManager(this._am, this.checkCb.bind(this));
cc.eventManager.addListener(this._checkListener, 1);
cc.log("开始检测版本");
this._am.checkUpdate();
this._updating = true;
},
onDestroy: function () {
if (this._updateListener) {
cc.eventManager.removeListener(this._updateListener);
this._updateListener = null;
}
if (this._am && !cc.sys.ENABLE_GC_FOR_NATIVE_OBJECTS) {
this._am.release();
this._am = null;
}
}
});
代码基本是复制粘贴的,只是把手动点击 改 自己动检测下载
cc.log(“资源更热完成—重启游戏”);
cc.game.restart();
这个重启后有执行么?
这个本地预置的描述文件可以直接写成json字符串,配置在这个脚本里,就不用load了。
fullPath = cc.url.raw(“resources/project.manifest”);
cc.log(“没有下载配置文件,使用本地配置”);
重启没执行, 这个方法只是读下当前最新的资源 版本
this._am = new jsb.AssetsManager("", this._storagePath, this.versionCompareHandle);
自己调用的应该是
AssetsManagerEx::AssetsManagerEx(const std::string& manifestUrl, const std::string& storagePath, const VersionCompareHandle& handle)
三个参数,第一个manifestUrl 为空的
if (manifestUrl.size() > 0)
{
loadLocalManifest(manifestUrl);
}
这段代码不走
但是重启后 自动调用了
AssetsManagerEx* AssetsManagerEx::create(const std::string& manifestUrl, const std::string& storagePath)
manifestUrl是下载后的配置文件,然后 走了 loadLocalManifest(manifestUrl); 把资源删除了
这个是异步的
是重启后 整个 start 都没执行,重启的时候 onDestroy 也没调用,手动调用了,也还是不行
和这个没关系的,我屏蔽测试过了
你说的这个方法在哪个方法里?start没执行的话,重启后执行的最先是哪个方法?
new jsb.AssetsManager(this.manifestUrl, storagePath) 我没有使用这个方法,
只有 new jsb.AssetsManager("", this._storagePath, this.versionCompareHandle);
这个热更新代码 都在这里,其他没地方
图片就是重启后自动调用的断点,
工程是重新build的,用的link
是default
可是这个方法在start里啊,那就是重启后执行start了吧?
你看这个方法是三个参数的 而且 第一个是空的 ,但是自动调用的 是两个参数的,第一个不为空
看屏幕下的log,start的方法也没执行,log没打印,
重启后,整个hotupdate,方法里 就执行一句话
收到消息 jsb.EventAssetsManager.ALREADY_UP_TO_DATE
打印是最新版本 ,然后没了
杀进程,重进游戏,又开始下载资源
