参照 : https://github.com/cocos-creator/tutorial-hot-update

一 , 模拟远程资源服务器

      Ⅰ, 方案 anywhere npm包

                   使用npm install anywhere -g 安装最新的服务器包, 如下

                   启动 anywhere 8860 

                            a, 在目录服务器目录下执行命令  anywhere 8860, 如下

                                

                            b, 可以在浏览器, 检查是否启动成功, 如下

二, 生成manifest文件

     命令准备  node version_generator.js -v 1.0.0 -u http://192.168.0.103:8860/remote-assets/ -s build/android/assets -d remote-assets

    step1 , 我们先要发不一个App版本( 构建 + 生成 )

step2 , 将version_generator.js文件考到项目的根目录

step3, 在项目的根目录中使用命令 node version_generator.js -v 1.0.0 -u http://192.168.0.103:8860/remote-assets/ -s build/android//assets -d remote-assets/ 生成

-u : 资源服务器根目录有remote-assets文件夹

-d : 生成remote-assets资源文件


三, 开始模拟

    ①, 使用夜神模拟器安装打好的App包 (此时是v1.0.0的包)

           

    ②,再次使用 version_generator.js 生成高级一版的更新包 , 步骤如下 (注意顺序)

        Ⅰ, 将更新过的资源保存 , 如下所示

        Ⅱ,"构建" , 注意此时不要再点击"生成"

        Ⅲ, 

                a,修改HotUpdate.ts 如下:

                b,使用 node version_generator.js -v 1.0.1 -u http://192.168.0.103:8860/remote-assets/ -s build/android/assets -d remote-assets , 生成更高级的更细包 , 注意v1.0.1 > v1.0.0

        Ⅳ, 正式模式资源更新模拟器

                 1, 在anywhere 所在文件夹中, 将项目根目录下的remote-assets考入到其中

                 2, 启动anywhere


    四, 结果



注: 资源服务器如下:


HotUpdate.ts

import { UpdatePanel } from './UpdatePanel';const jsb = (<any>window).jsb;// Custom manifest removed the following assets:// 1. res/raw-assets/2a/2a40e5e7-4c4a-4350-9e5d-76757755cdd2.png// 2. res/raw-assets/2d/2d86a854-63c4-4b90-8b88-a4328b8526c2.png// So when custom manifest used, you should be able to find them in downloaded remote assets// let UIRLFILE = "http://192.168.0.1:8080/server/" + gameName;// let remoteManifestUrl = this._storagePath + "/project.manifest";// this.manifestUrl = remoteManifestUrl;var customManifestStr = JSON.stringify({    "packageUrl": "http://192.168.0.103:8860/remote-assets/",    "remoteManifestUrl": "http://192.168.0.103:8860/remote-assets/project.manifest",    "remoteVersionUrl": "http://192.168.0.103:8860/remote-assets/version.manifest",    "version": "1.0.1",    "assets": {    },    "searchPaths": []});import { _decorator, Component, Node, Label, ProgressBar, Asset, game, sys } from 'cc';const { ccclass, property } = _decorator;@ccclass('HotUpdate')export class HotUpdate extends Component {    @property(UpdatePanel)    panel: UpdatePanel = null!;    @property(Asset)    manifestUrl: Asset = null!;    @property(Node)    updateUI: Node = null!;    private _updating = false;    private _canRetry = false;    private _storagePath = '';    private _am: jsb.AssetsManager = null!;    private _checkListener = null;    private _updateListener = null;    private _failCount = 0;    private versionCompareHandle: (versionA: string, versionB: string) => number = null!;    checkCb(event: any) {        console.log('Code: ' + event.getEventCode());        switch (event.getEventCode()) {            case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:                this.panel.info.string = "No local manifest file found, hot update skipped.";                break;            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:                alert(`BBB : ${ JSON.stringify( event ) }`);                this.panel.info.string = "Fail to download manifest file, hot update skipped.";                break;            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:                this.panel.info.string = "Already up to date with the latest remote version.";                break;            case jsb.EventAssetsManager.NEW_VERSION_FOUND:                this.panel.info.string = 'New version found, please try to update. (' + Math.ceil(this._am.getTotalBytes() / 1024) + 'kb)';                this.panel.checkBtn.active = false;                this.panel.fileProgress.progress = 0;                this.panel.byteProgress.progress = 0;                break;            default:                return;        }        this._am.setEventCallback(null!);        this._checkListener = null;        this._updating = false;    }    updateCb(event: any) {        var needRestart = false;        var failed = false;        switch (event.getEventCode()) {            case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:                this.panel.info.string = 'No local manifest file found, hot update skipped.';                failed = true;                break;            case jsb.EventAssetsManager.UPDATE_PROGRESSION:                this.panel.byteProgress.progress = event.getPercent();                this.panel.fileProgress.progress = event.getPercentByFile();                this.panel.fileLabel.string = event.getDownloadedFiles() + ' / ' + event.getTotalFiles();                this.panel.byteLabel.string = event.getDownloadedBytes() + ' / ' + event.getTotalBytes();                console.log(this.panel.fileLabel.string, this.panel.byteLabel.string);                var msg = event.getMessage();                if (msg) {                    this.panel.info.string = 'Updated file: ' + msg;                    // cc.log(event.getPercent()/100 + '% : ' + msg);                }                break;            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:                alert(`AAA : ${ JSON.stringify( event ) }`);                this.panel.info.string = 'Fail to download manifest file, hot update skipped.';                failed = true;                break;            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:                this.panel.info.string = 'Already up to date with the latest remote version.';                failed = true;                break;            case jsb.EventAssetsManager.UPDATE_FINISHED:                this.panel.info.string = 'Update finished. ' + event.getMessage();                needRestart = true;                break;            case jsb.EventAssetsManager.UPDATE_FAILED:                this.panel.info.string = 'Update failed. ' + event.getMessage();                this.panel.retryBtn.active = true;                this._updating = false;                this._canRetry = true;                break;            case jsb.EventAssetsManager.ERROR_UPDATING:                this.panel.info.string = 'Asset update error: ' + event.getAssetId() + ', ' + event.getMessage();                break;            case jsb.EventAssetsManager.ERROR_DECOMPRESS:                this.panel.info.string = event.getMessage();                break;            default:                break;        }        if (failed) {            this._am.setEventCallback(null!);            this._updateListener = null;            this._updating = false;        }        if (needRestart) {            this._am.setEventCallback(null!);            this._updateListener = null;            // 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);            // This value will be retrieved and appended to the default search path during game startup,            // please refer to samples/js-tests/main.js for detailed usage.            // !!! Re-add the search paths in main.js is very important, otherwise, new scripts won't take effect.            localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));            jsb.fileUtils.setSearchPaths(searchPaths);            // restart game.            setTimeout(() => {                game.restart();            }, 1000)        }    }    loadCustomManifest() {        if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {            var manifest = new jsb.Manifest(customManifestStr, this._storagePath);            this._am.loadLocalManifest(manifest, this._storagePath);            this.panel.info.string = 'Using custom manifest';        }    }    retry() {        if (!this._updating && this._canRetry) {            this.panel.retryBtn.active = false;            this._canRetry = false;            this.panel.info.string = 'Retry failed Assets...';            this._am.downloadFailedAssets();        }    }    checkUpdate() {        if (this._updating) {            this.panel.info.string = 'Checking or updating ...';            return;        }        if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {            var url = this.manifestUrl.nativeUrl;            this._am.loadLocalManifest(url);        }        if (!this._am.getLocalManifest() || !this._am.getLocalManifest().isLoaded()) {            this.panel.info.string = 'Failed to load local manifest ...';            return;        }        this._am.setEventCallback(this.checkCb.bind(this));        this._am.checkUpdate();        this._updating = true;    }    hotUpdate() {        if (this._am && !this._updating) {            this._am.setEventCallback(this.updateCb.bind(this));            if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {                var url = this.manifestUrl.nativeUrl;                this._am.loadLocalManifest(url);            }            this._failCount = 0;            this._am.update();            this.panel.updateBtn.active = false;            this._updating = true;        }    }    show() {        if (this.updateUI.active === false) {            this.updateUI.active = true;        }    }    // use this for initialization    onLoad() {        // Hot update is only available in Native build        if(!sys.isNative){            return;        }        if (!jsb) {            return;        }        this._storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'blackjack-remote-asset');        console.log('Storage path for remote asset : ' + this._storagePath);        // Setup your own version compare handler, versionA and B is versions in string        // if the return value greater than 0, versionA is greater than B,        // if the return value equals 0, versionA equals to B,        // if the return value smaller than 0, versionA is smaller than B.        this.versionCompareHandle = function (versionA: string, versionB: string) {            console.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;            }        };        // Init with empty manifest url for testing custom manifest        this._am = new jsb.AssetsManager('', this._storagePath, this.versionCompareHandle);        var panel = this.panel;        // Setup the verification callback, but we don't have md5 check function yet, so only print some message        // Return true if the verification passed, otherwise return false        this._am.setVerifyCallback(function (path: string, asset: any) {            // 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;            }        });        this.panel.info.string = 'Hot update is ready, please check or directly update.';        this.panel.fileProgress.progress = 0;        this.panel.byteProgress.progress = 0;    }    onDestroy() {        if (this._updateListener) {            this._am.setEventCallback(null!);            this._updateListener = null;        }    }}

注意 : 项目根目录下的 "extensions"文件夹

©著作权归作者所有:来自51CTO博客作者Aonaufly的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. Pod The node had condition: [DiskPressure]
  2. PHP:回调函数/递归函数/数组函数/二维数组里的键值name换成user
  3. 推荐使用 SSH 方式连接 Git 服务
  4. 驰骋工作流引擎设计系列02 流程实例的生成设计
  5. 0429作业
  6. php之数组键名更换,快速生成数组与数组过滤
  7. 你还在手撕微服务?快试试 go-zero 的微服务自动生成
  8. 整合SSM框架应用
  9. [记录点滴] 一个解决Lua 随机数生成问题的办法

随机推荐

  1. 【Android】如何调节屏幕亮度,关闭屏幕
  2. 如何申请Android Map API Key
  3. Androkd开发坏境配置以及常用插件
  4. ListView高级用法
  5. Android(安卓)用 libusb 操作 USB 设备,无
  6. Android证书创建之 keytool 错误:java.io.
  7. android开发之实现应用内音乐的播放
  8. android studio本地配置gradle遇到的坑以
  9. Android几种动画的总结(MaterialAnimatio
  10. ADB—查看日志