热更新请教

  • Creator 版本:2.0.9

  • 目标平台: Android / 模拟器 -->

  • 详细报错信息,包含调用堆栈:

  • 有所代码就下面那些,用插件生成相关东西,把project.manifest给manifestUrl。给服务器拷一份(res,src,project.manifest,version.manifest)

  • 文件服务器网页可以正常访问

  • 检查更新一直提示 code 2

提示信息:

Enable batch GL commands optimization!
src/cocos2d-jsb.js:7383 Cocos Creator v2.0.9
assets/scripts/updata.js:183 热更新部分
assets/scripts/updata.js:185 Storage path for remote asset : D:\CocosCreator\resources\cocos2d-x\simulator\win32\remote-asset
assets/scripts/updata.js:186 Local manifest URL : d:/Documents/NewProject_29/library/imports/8c/8cc9d7c8-8151-4f86-855c-a42d1b1fd130.manifest
assets/scripts/updata.js:190 搜索路径 (9) ["C:/Users/Administrator/AppData/Local/Simulator/debugruntime/", "D:\CocosCreator\resources\cocos2d-x\simulator\win32\/", "D:/CocosCreator/resources/cocos2d-x/simulator/", "D:/CocosCreator/resources/cocos2d-x/simulator/", "D:\CocosCreator\resources\cocos2d-x\simulator\win32\/", "D:/CocosCreator/resources/cocos2d-x/simulator/win32/", "D:/CocosCreator/resources/cocos2d-x/simulator/win32/", "D:/CocosCreator/resources/cocos2d-x/simulator/win32/", "D:\CocosCreator\resources\cocos2d-x\simulator\win32\/"]
assets/scripts/updata.js:25 Code: 2
assets/scripts/updata.js:36 Fail to download manifest file, hot update skipped.ERROR_PARSE_MANIFEST,下载manifest文件失败,跳过更新

代码:

插件

var fs = require('fs');
var path = require('path');
var crypto = require('crypto');

var manifest = {
    packageUrl: 'http://192.168.100.100:80/',
    remoteManifestUrl: 'http://192.168.100.100:80/project.manifest',
    remoteVersionUrl: 'http://192.168.100.100:80/version.manifest',
    version: '1.0.1',
    assets: {},
    searchPaths: []
};

var dest = 'assets/';
var src = 'build/jsb-default/';

// Parse arguments
var i = 2;
while ( i < process.argv.length) {
    var arg = process.argv[i];

    switch (arg) {
    case '--url' :
    case '-u' :
        var url = process.argv[i+1];
        manifest.packageUrl = url;
        manifest.remoteManifestUrl = url + 'project.manifest';
        manifest.remoteVersionUrl = url + 'version.manifest';
        i += 2;
        break;
    case '--version' :
    case '-v' :
        manifest.version = process.argv[i+1];
        i += 2;
        break;
    case '--src' :
    case '-s' :
        src = process.argv[i+1];
        i += 2;
        break;
    case '--dest' :
    case '-d' :
        dest = process.argv[i+1];
        i += 2;
        break;
    default :
        i++;
        break;
    }
}


function readDir (dir, obj) {
    var stat = fs.statSync(dir);
    if (!stat.isDirectory()) {
        return;
    }
    var subpaths = fs.readdirSync(dir), subpath, size, md5, compressed, relative;
    for (var i = 0; i < subpaths.length; ++i) {
        if (subpaths[i][0] === '.') {
            continue;
        }
        subpath = path.join(dir, subpaths[i]);
        stat = fs.statSync(subpath);
        if (stat.isDirectory()) {
            readDir(subpath, obj);
        }
        else if (stat.isFile()) {
            // Size in Bytes
            size = stat['size'];
            md5 = crypto.createHash('md5').update(fs.readFileSync(subpath, 'binary')).digest('hex');
            compressed = path.extname(subpath).toLowerCase() === '.zip';

            relative = path.relative(src, subpath);
            relative = relative.replace(/\\/g, '/');
            relative = encodeURI(relative);
            obj[relative] = {
                'size' : size,
                'md5' : md5
            };
            if (compressed) {
                obj[relative].compressed = true;
            }
        }
    }
}

var mkdirSync = function (path) {
    try {
        fs.mkdirSync(path);
    } catch(e) {
        if ( e.code != 'EEXIST' ) throw e;
    }
}

// Iterate res and src folder
readDir(path.join(src, 'src'), manifest.assets);
readDir(path.join(src, 'res'), manifest.assets);

var destManifest = path.join(dest, 'project.manifest');
var destVersion = path.join(dest, 'version.manifest');

mkdirSync(dest);

fs.writeFile(destManifest, JSON.stringify(manifest), (err) => {
  if (err) throw err;
  console.log('Manifest successfully generated');
});

delete manifest.assets;
delete manifest.searchPaths;
fs.writeFile(destVersion, JSON.stringify(manifest), (err) => {
  if (err) throw err;
  console.log('Version successfully generated');
});

脚本

cc.Class({
    extends: cc.Component,
    properties: {
		//这里指向生成的project.manifest文件
        manifestUrl: {
	          type: cc.Asset,			
                  default: null,
        },
        //这个没用的
        str:{ 
		type:cc.Label,
		default:null,			
	}
    },
	// 检擦更新
    checkCb: function (event) {
        cc.log('Code: ' + event.getEventCode());
		this.str.string = event.getEventCode()+"code";
        switch (event.getEventCode())
        {
           	//监听更新过程中的事件
			case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
                cc.log ("No local manifest file found, hot update skipped.没有本地manifest文件,跳过更新");
                break;
            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
				cc.log ("Fail to download manifest file, hot update skipped.ERROR_DOWNLOAD_MANIFEST,下载manifest文件失败,跳过更新");
                break;
            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
                cc.log ("Fail to download manifest file, hot update skipped.ERROR_PARSE_MANIFEST,下载manifest文件失败,跳过更新");
                break;
            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
                cc.log("Already up to date with the latest remote version.已经是最新版本,无需更新");
                break;
            case jsb.EventAssetsManager.NEW_VERSION_FOUND:
                cc.log('New version found, please try to update.发现新版本准备更新');
                this._needUpdate = true;                
                break;
            default:
                return;
        }
		this._am.setEventCallback(null);	//注销监听
        this.hotUpdate();
    },
    updateCb: function (event) {
        var needRestart = false;
        var failed = false;
		this.str.string = event.getEventCode()+"updateCb";
        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:
                //this.tip.getComponent(cc.Label).string = "正在更新";
                cc.log( event.getDownloadedFiles() + ' / ' + event.getTotalFiles());
                cc.log( event.getDownloadedBytes() + ' / ' + event.getTotalBytes());
                var percent = event.getPercent();
                var percentByFile = event.getPercentByFile();
                //this.file.getComponent(cc.Label).string = "下载文件数: " + event.getDownloadedFiles() + ' / ' + event.getTotalFiles();
                var msg = event.getMessage();
                if (msg) {
                    cc.log(msg);
                }
                //this.progress.getComponent(cc.Label).string = "文件进度:" + percent.toFixed(2) * 100 + "%"
                cc.log(percent.toFixed(2)* 100 + '%');
                break;
            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
                cc.log('Fail to download manifest file, hot update skipped.');
                //this.tip.getComponent(cc.Label).string = "下载失败";
                failed = true;
                break;
            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
                cc.log('Already up to date with the latest remote version.');
                //this.tip.getComponent(cc.Label).string = "已经是最新版本";
                failed = true;
                break;
            case jsb.EventAssetsManager.UPDATE_FINISHED:
                cc.log('Update finished. ' + event.getMessage());
                //this.tip.getComponent(cc.Label).string = "更新完成:正在重启游戏";
                needRestart = true;
                break;
            case jsb.EventAssetsManager.UPDATE_FAILED:
                cc.log('Update failed. ' + 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;
                }
                break;
            case jsb.EventAssetsManager.ERROR_UPDATING:
                cc.log('Asset update error: ' + 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._am.setEventCallback(null);
        }
        if (needRestart) { //重新启动游戏
            //cc.eventManager.removeListener(this._updateListener);
			this._am.setEventCallback(null);
            // Prepend the manifest's search path
            var searchPaths = jsb.fileUtils.getSearchPaths();
            var newPaths = this._am.getLocalManifest().getSearchPaths();
            Array.prototype.unshift(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.
            cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
            console.log("测试===getPath",searchPaths);
            jsb.fileUtils.setSearchPaths(searchPaths);
            cc.game.restart();
        }
    },
    hotUpdate: function () {
        if (this._am && this._needUpdate) {
            this._updateListener = new jsb.EventListenerAssetsManager(this._am, this.updateCb.bind(this));
            //cc.eventManager.addListener(this._updateListener, 1);
			this._am.setEventCallback(this._updateListener, 1);
            this._failCount = 0;
            this._am.update();
        }
    },
	//初始AssetsManager
    onLoad: function () {
        if (!cc.sys.isNative) {
            return;
        }
        console.log("热更新部分");
        var storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'remote-asset');
        cc.log('Storage path for remote asset : ' + storagePath);
        cc.log('Local manifest URL : ' + this.manifestUrl);		
		this._am = new jsb.AssetsManager(this.manifestUrl, storagePath);
        var searchPaths = jsb.fileUtils.getSearchPaths();

        cc.log("搜索路径",searchPaths);
        //this._am.retain();  
        this._needUpdate = false;

        if (this._am.getLocalManifest().isLoaded())
        {
            this._checkListener = new jsb.EventListenerAssetsManager(this._am, this.checkCb.bind(this));
            //cc.eventManager.addListener(this._checkListener, 1);
			this._am.setEventCallback(this._checkListener, 1);
            this._am.checkUpdate();
        }
		
    },
    onDestroy: function () {
        this._am && this._am.release();
    }
});

大佬 你在哪

求指点啊 ,随便指点下都好啊

解决了吗大佬?我也有同样的问题

你是用内网测的吗?设备是不是安卓9以上的设备,安卓9以上的设备是不支持http的需要更改原生http支持配置(百度可找)。或者换低一点的测试设备测试,或者降低targeApi。