热更代码基本是按github上的版本写的
var Log = console;
cc.Class({
extends: cc.Component,
properties: {
fileProgress: cc.ProgressBar,
byteProgress: cc.ProgressBar,
infomation: cc.Label,
manifestUrl: cc.RawAsset,
choiceBox: cc.Prefab,
_updating: false,
_canRetry: false,
_am: null,
_updateListener: null,
_checkListener: null,
_failCount: 5
},
onLoad: function() {
var that = this;
cc.view.setDesignResolutionSize(720, 1280, cc.ResolutionPolicy.EXACT_FIT);
that._failCount = 5;
if (!cc.sys.isNative) {
return;
}
var storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'werewolfkill-remote-asset');
Log.error('[hot] save path : ' + storagePath);
that._am = new jsb.AssetsManager(that.manifestUrl, storagePath);
if (!cc.sys.ENABLE_GC_FOR_NATIVE_OBJECTS) {
that._am.retain();
}
that._am.setVersionCompareHandle(function(versionA, versionB) {
Log.error("[hot] 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;
}
});
that._am.setVerifyCallback(function(path, asset) {
var compressed = asset.compressed;
var expectedMD5 = asset.md5;
var relativePath = asset.path;
var size = asset.size;
if (compressed) {
Log.error("[hot] Verification passed : " + relativePath);
return true;
} else {
Log.error("[hot] Verification passed : " + relativePath + ' (' + expectedMD5 + ')');
return true;
}
});
if (cc.sys.os === cc.sys.OS_ANDROID) {
that._am.setMaxConcurrentTask(2);
}
that.fileProgress.progress = 0;
that.byteProgress.progress = 0;
that.checkUpdate();
},
onDestroy: function() {
var that = this;
if (that._updateListener) {
cc.eventManager.removeListener(that._updateListener);
that._updateListener = null;
}
if (that._checkListener) {
cc.eventManager.removeListener(that._checkListener);
that._checkListener = null;
}
if (that._am && !cc.sys.ENABLE_GC_FOR_NATIVE_OBJECTS) {
that._am.release();
that._am = null;
}
},
checkUpdate: function() {
var that = this;
if (that._updating) {
return;
}
if (!that._am.getLocalManifest().isLoaded()) {
return;
}
that._checkListener = new jsb.EventListenerAssetsManager(that._am, that.checkCb.bind(that));
cc.eventManager.addListener(that._checkListener, 1);
this._am.checkUpdate();
this._updating = true;
},
hotUpdate: function() {
var that = this;
Log.error('[hot] updateCheck', !!that._am, !that._updating);
if (that._am && !that._updating) {
that._updateListener = new jsb.EventListenerAssetsManager(that._am, that.updateCb.bind(that));
cc.eventManager.addListener(that._updateListener, 1);
that._am.update();
that._updating = true;
}
},
retry: function() {
var that = this;
if (that._updating || !that._canRetry) {
return;
}
that._canRetry = false;
that._am.downloadFailedAssets();
},
checkCb: function(event) {
this._updating = false;
Log.error('[hot] check event');
var that = this;
Log.error('[hot] check-code : ' + event.getEventCode());
switch (event.getEventCode()) {
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
that.infomation.string = "本地升级文件未找到";
that.errorCb(event.getEventCode());
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
Log.error('[hot] download-error : manifest');
that.infomation.string = "获取更新信息失败";
that.errorCb(event.getEventCode());
break;
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
Log.error('[hot] parse-error : manifest');
that.infomation.string = "解析更新信息失败";
that.errorCb(event.getEventCode());
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
that.infomation.string = '已是最新版本';
cc.director.loadScene('auth');
break;
case jsb.EventAssetsManager.NEW_VERSION_FOUND:
that.infomation.string = '发现新版本,正在升级';
that.fileProgress.progress = 0;
that.byteProgress.progress = 0;
that.hotUpdate();
break;
default:
return;
}
cc.eventManager.removeListener(that._checkListener);
that._checkListener = null;
that._updating = false;
},
updateCb: function(event) {
Log.error('[hot] update event');
var that = this;
var needRestart = false;
var failed = false;
switch (event.getEventCode()) {
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
that.infomation.string = "本地升级文件未找到";
that.errorCb(event.getEventCode());
failed = true;
break;
case jsb.EventAssetsManager.UPDATE_PROGRESSION:
that.byteProgress.progress = event.getPercent() / 100;
that.fileProgress.progress = event.getPercentByFile() / 100;
var msg = event.getMessage();
if (msg) {
that.infomation.string = '更新 : ' + msg;
Log.error('[hot] ' + event.getPercent().toFixed(2) + '% : ' + msg + ' -2');
}
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
that.infomation.string = '获取更新信息失败';
that.errorCb(event.getEventCode());
failed = true;
break;
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
that.infomation.string = '解析更新信息失败';
that.errorCb(event.getEventCode());
failed = true;
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
that.infomation.string = '已是最新版本';
cc.director.loadScene('auth');
failed = true;
break;
case jsb.EventAssetsManager.UPDATE_FINISHED:
Log.error('[hot] update finish' + event.getMessage() + ' -2');
that.infomation.string = '更新完毕';
needRestart = true;
break;
case jsb.EventAssetsManager.UPDATE_FAILED:
Log.error('[hot] update fail' + event.getMessage() + ' -2');
that.infomation.string = '更新失败';
that._updating = false;
that._canRetry = true;
if (that._failCount-- > 0) {
that.retry();
} else {
that.infomation.string = '网络不佳,请重试';
that.errorCb(event.getEventCode());
}
break;
case jsb.EventAssetsManager.ERROR_UPDATING:
Log.error('[hot] update error' + event.getAssetId() + ' => ' + event.getMessage() + ' -2');
that.infomation.string = '更新异常 : ' + event.getAssetId() + ', ' + event.getMessage();
break;
case jsb.EventAssetsManager.ERROR_DECOMPRESS:
that.infomation.string = event.getMessage();
break;
default:
break;
}
if (failed) {
cc.eventManager.removeListener(that._updateListener);
that._updateListener = null;
that._updating = false;
}
if (needRestart) {
cc.eventManager.removeListener(that._updateListener);
that._updateListener = null;
var searchPaths = jsb.fileUtils.getSearchPaths();
var newPaths = this._am.getLocalManifest().getSearchPaths();
Log.error('[set] newpaths ' + JSON.stringify(newPaths));
// Array.prototype.unshift(searchPaths, newPaths);
searchPaths = newPaths.concat(searchPaths);
// var path = [];
// for (var i = 0; i < searchPaths.length; i++) {
// var p = searchPaths[i];
// var same = false;
// for (var j = 0; j < path.length; j++) {
// if (path[j] == p) {
// same = true;
// }
// }
// if (!same) {
// path.push(p);
// }
// }
// searchPaths = path;
Log.error('[set] HotUpdateSearchPaths ' + JSON.stringify(searchPaths));
cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
cc.sys.localStorage.setItem('restart', true);
jsb.fileUtils.setSearchPaths(searchPaths);
cc.game.restart();
}
},
errorCb: function(code) {
var that = this;
var choice = cc.instantiate(that.choiceBox);
choice.getComponent('choiceBoxScript').setText('' + code + '\n更新失败 请检查网络后再试\n是否要重启(点击是重启,否关闭)', function() {
cc.game.restart();
}, function() {
cc.game.end();
});
choice.parent = cc.director.getScene();
},
});
properties中的manifestUrl是第一次运行更新包脚本时的project.manifest。 求大神解惑。