cocos creator热更新-菜鸟教程
!写在前面 最后有源码
说下几个重要的环节:首先是version_generator.js文件 可以在官方案例下载
这几个属性可以直接写在version文件里 需要下载nodeJs 用来生成 manifest 文件第一次构建以后需要在mani.js里加上搜索路劲 main.js文件在build\jsb-default下
if (jsb) { var hotUpdateSearchPaths = localStorage.getItem('HotUpdateSearchPaths'); if (hotUpdateSearchPaths) { jsb.fileUtils.setSearchPaths(JSON.parse(hotUpdateSearchPaths)); }} 然后就可以编译了第一个apk包基本就这些东西 然后更新包把版本号提升一下
在随便改点东西重新构建一下然后用nodejs重新生成 manifest文件 然后把构建后的 project.manifest version.manifest src res 4个文件放在服务器的remote-assets文件下面
注意服务器网站的文件类型后缀识别(.json,.manifest,jsc) 不然可能更新下载失败如果没有检测到更新那肯定是 manifest文件的问题
第一次如果没有manifest文件 就先构建好了 用nodejs生成manifest文件放在属性里直接贴代码 有问题可以留言
cc.Class({
extends: cc.Component,
properties: {
manifestUrl: {
default: null,
type: cc.Asset
},
versionLabel: cc.Label,
btn_check: cc.Button,
btn_update: cc.Button,
tipLabel: cc.Label,
byteProgress: cc.ProgressBar,
byteLabel: cc.Label,
fileProgress: cc.ProgressBar,
fileLabel: cc.Label,
},
start() {
this.updating = false
this.canRetry = false
this.btn_update.node.active = false
this.byteProgress.node.active = false
this.fileProgress.node.active = false
this.tipLabel.node.active = false
if (!cc.sys.isNative) return
//获取存储路径
this.storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'remote-asset')
//版本比较函数
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 (let 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)
this.am.setVerifyCallback(function (path, asset) {
console.log('设置回调验证' + asset)
var compressed = asset.compressed;
var expectedMD5 = asset.md5;
var relativePath = asset.path;
var size = asset.size;
if (compressed) {
this.tipLabel.string = "Verification passed : " + relativePath;
return true;
}
else {
this.tipLabel.string = "Verification passed : " + relativePath + ' (' + expectedMD5 + ')';
return true;
}
}.bind(this));
if (cc.sys.os === cc.sys.OS_ANDROID) {
// Some Android device may slow down the download process when concurrent tasks is too much.
// The value may not be accurate, please do more test and find what's most suitable for your game.
this.am.setMaxConcurrentTask(2);
console.log('安卓开启双线程更新模式')
}
var url = this.manifestUrl.nativeUrl;
if (cc.loader.md5Pipe) {
url = cc.loader.md5Pipe.transformURL(url);
}
this.am.loadLocalManifest(url);
var version = this.am.getLocalManifest().getVersion();
console.log('version=' + version)
this.versionLabel.string = version
this.fileProgress.progress = 0;
this.byteProgress.progress = 0;
//检查更新
this.checkUpdate()
},
checkUpdate() {
this.tipLabel.string = '检查更新';
var state = this.am.getState()
//if (state=== jsb.AssetsManager.State.UNINITED) {
// Resolve md5 url
console.log('检查更新')
this.am.setEventCallback(this.checkCb.bind(this));
this.failCount = 0;
this.am.checkUpdate();
this.updating = true;
// }
},
checkCb(event) {
console.log('Code: ' + event.getEventCode());
switch (event.getEventCode()) {
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
this.tipLabel.string = '本地文件丢失'
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
this.tipLabel.string = "下载远程mainfest文件错误.";
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
this.tipLabel.string = "已经是最新版本.";
break;
case jsb.EventAssetsManager.NEW_VERSION_FOUND: //显示更新按钮 调用hotUpdate方法
this.tipLabel.node.active = true
this.tipLabel.string = '有新版本发现,请点击更新.';
this.btn_update.node.active = true
this.btn_check.interactable = false;
break;
default:
return;
}
this.am.setEventCallback(null);
this.updating = false;
},
hotUpdate: function () {
if (this.am && !this.updating) {
console.log('更新')
this.am.setEventCallback(this.updateCb.bind(this));
if (this.am.getState() === jsb.AssetsManager.State.UNINITED) {
// Resolve md5 url
var url = this.manifestUrl.nativeUrl;
if (cc.loader.md5Pipe) {
url = cc.loader.md5Pipe.transformURL(url);
}
this.am.loadLocalManifest(url);
console.log('本地地址' + url)
}
this.failCount = 0;
this.am.update();
this.updating = true;
}
},
updateCb(event) {
console.log('Code: ' + event.getEventCode());
var needRestart = false;
var failed = false;
this.byteProgress.node.active = true
this.fileProgress.node.active = true
switch (event.getEventCode()) {
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
this.tipLabel.string = '本地版本文件丢失,无法更新.';
failed = true;
break;
case jsb.EventAssetsManager.UPDATE_PROGRESSION:
this.byteProgress.progress = event.getPercent();
this.fileProgress.progress = event.getPercentByFile();
this.fileLabel.string = event.getDownloadedFiles() + ' / ' + event.getTotalFiles();
this.byteLabel.string = event.getDownloadedBytes() + ' / ' + event.getTotalBytes();
var msg = event.getMessage();
if (msg) {
this.tipLabel.string = 'Updated file: ' + msg;
console.log(event.getPercent() / 100 + '% : ' + msg);
}
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
this.tipLabel.string = '下载远程版本文件失败.';
failed = true;
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
this.tipLabel.string = '当前为最新版本.';
failed = true;
break;
case jsb.EventAssetsManager.UPDATE_FINISHED:
this.tipLabel.string = '更新完成. ' + event.getMessage();
needRestart = true;
break;
case jsb.EventAssetsManager.UPDATE_FAILED:
this.proc.string = '更新失败. ' + event.getMessage();
this.btn_rectry.interactable = true;
this.updating = false;
this.canRetry = true;
this.btn_update.interactable = false
break;
case jsb.EventAssetsManager.ERROR_UPDATING:
this.tipLabel.string = '资源更新错误: ' + event.getAssetId() + ', ' + event.getMessage();
this.btn_update.interactable = false
break;
case jsb.EventAssetsManager.ERROR_DECOMPRESS:
this.tipLabel.string = event.getMessage();
break;
default:
break;
}
if (failed) {
this.am.setEventCallback(null);
this.updating = false;
}
//下载完成
if (needRestart) {
this.am.setEventCallback(null);
console.log('热更完成')
// Prepend the manifest's search path
var searchPaths = jsb.fileUtils.getSearchPaths();
var newPaths = this.am.getLocalManifest().getSearchPaths();
console.log(JSON.stringify(newPaths));
Array.prototype.unshift.apply(searchPaths, newPaths);
cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
jsb.fileUtils.setSearchPaths(searchPaths);
cc.audioEngine.stopAll();
cc.game.restart();
}
},
retry: function () {
if (!this.updating && this.canRetry) {
this.panel.retryBtn.active = false;
this.canRetry = false;
this.tipLabel.string = 'Retry failed Assets...';
this.am.downloadFailedAssets();
}
},
});