!寫(xiě)在前面 最后有源碼
說(shuō)下幾個(gè)重要的環(huán)節(jié):首先是version_generator.js文件 可以在官方案例下載??



第一次構(gòu)建以后需要在mani.js里加上搜索路勁? main.js文件在build\jsb-default下

? ? ? ? ? ? ? ? ? ? 第一個(gè)apk包基本就這些東西 然后更新包把版本號(hào)提升一下

? ??然后用nodejs重新生成?manifest文件? ?然后把構(gòu)建后的?project.manifest? ?version.manifest? ? src? res 4個(gè)文件放在服務(wù)器的remote-assets文件下面??


? ? ? ? 如果沒(méi)有檢測(cè)到更新那肯定是?manifest文件的問(wèn)題??

直接貼代碼? 有問(wèn)題可以留言
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
? ? ? ? //獲取存儲(chǔ)路徑
? ? ? ? this.storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'remote-asset')
? ? ? ? //版本比較函數(shù)
? ? ? ? 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
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? //創(chuàng)建資源管理對(duì)象
? ? ? ? this.am = new jsb.AssetsManager('', this.storagePath, this.versionCompareHandle)
? ? ? ? this.am.setVerifyCallback(function (path, asset) {
? ? ? ? ? ? console.log('設(shè)置回調(diào)驗(yàn)證' + 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('安卓開(kāi)啟雙線程更新模式')
? ? ? ? }
? ? ? ? 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 = "下載遠(yuǎn)程mainfest文件錯(cuò)誤.";
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
? ? ? ? ? ? ? ? this.tipLabel.string = "已經(jīng)是最新版本.";
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case jsb.EventAssetsManager.NEW_VERSION_FOUND:? ? //顯示更新按鈕 調(diào)用hotUpdate方法
? ? ? ? ? ? ? ? this.tipLabel.node.active = true
? ? ? ? ? ? ? ? this.tipLabel.string = '有新版本發(fā)現(xiàn),請(qǐng)點(diǎn)擊更新.';
? ? ? ? ? ? ? ? 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 = '本地版本文件丟失,無(wú)法更新.';
? ? ? ? ? ? ? ? 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 = '下載遠(yuǎn)程版本文件失敗.';
? ? ? ? ? ? ? ? failed = true;
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
? ? ? ? ? ? ? ? this.tipLabel.string = '當(dāng)前為最新版本.';
? ? ? ? ? ? ? ? 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 = '資源更新錯(cuò)誤: ' + 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();
? ? ? ? }
? ? },
});