清空临时缓存文件夹的资源temp,会导致游戏资源丢失?

热更新完成后重启游戏,清空临时文件夹temp下的资源,会导致资源找不到

哪个temp文件夹,可否把路径发一下,如果清除的是APP的缓存目录,资源是会加载APP包里的资源。

var beiMiCommon = require(“BeiMiCommon”);
var MD5 = require(“MD5”);
cc.Class({
extends: beiMiCommon,

properties: {
    manifestUrl: {
        type: cc.Asset,
        default: null
    },
    progressBar: {
        type: cc.ProgressBar,
        default: null
    },
    progressBarNode: {
        type: cc.Node,
        default: null
    },
    progress: {
        type: cc.Label,
        default: null
    },
    bytes: {
        type: cc.Label,
        default: null
    },
    files: {
        type: cc.Label,
        default: null
    },
    curVersion: {
        type: cc.Label,
        default: null
    },
    lastVersion: {
        type: cc.Label,
        default: null
    },
    updateContentDesc: {
        type: cc.Label,
        default: null
    },
    tips: {
        type: cc.Label,
        default: null
    },
    updateTips: {
        type: cc.Node,
        default: null
    },
    logo: {
        type: cc.Node,
        default: null
    },
    desc: {
        type: cc.Node,
        default: null
    },
    main: {
        type: cc.Node,
        default: null
    },
    version: {
        type: cc.Node,
        default: null
    },
    _canRetry: false,
    _needUpdate: false,
    _storagePath: '',
    _hotUpdateName: 'zpsuoha-remote-asset'
},
checkCb: function (event) {
    console.log('Code: ' + event.getEventCode());
    switch (event.getEventCode()) {
        case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
            this.tips.string = "未检测到更新插件,跳过更新";
            break;
        case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
            this.tips.string = "更新插件下载失败,跳过更新";
            break;
        case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
            this.tips.string = "解压热更新插件失败,跳过更新";
            break;
        case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
            this.tips.string = "已是最新版本";
            break;
        case jsb.EventAssetsManager.NEW_VERSION_FOUND:
            this.tips.string = '发现新版本,即将更新';
            this.prepareForUpdate();
            this._needUpdate = true;
            break;
        default:
            return;
    }
    console.log(this.tips.string);

    this._am.setEventCallback(null);
    this.checkNativeVersion(this._needUpdate);
    if (this._needUpdate) {
        console.log("异步自动执行更新操作");
        this.scheduleOnce(this.hotUpdate, 0.5);
    } else {
        this.showLoginView();
    }
},
showLoginView() {
    this.progressBar.progress = 1;
    console.log("更新结束,展示登录按钮");
    this.scheduleOnce(function () {
        this.main.active = true;
        this.logo.active = true;

        this.progressBarNode.active = false;
        this.desc.active = false;
        this.updateTips.active = false;
        this._failCount = 0;
    }, 0.3);
},
prepareForUpdate() {
    console.log("切换到更新界面");
    this.files.string = "0/0";
    this.bytes.string = "0k/0k";

    this.logo.active = false;
    this.updateTips.active = true;
    let isIOS = true;
    if (cc.sys.os === cc.sys.OS_ANDROID) {
        isIOS = false;
    }
    cc.beimi.http.httpGet("/api/player/getLastVersionUpdateLog?isIOS=" + isIOS, this.showChangeLog, this.showChangeLog, this);
},
showChangeLog(changelog, that) {
    console.log("查询到更新日志:", changelog);
    that.updateContentDesc.string = changelog ? changelog : "版本更新日志加载失败";
    //加载更新日志,再进行展示
    that.desc.active = true;
},
updateCb: function (event) {
    let needRestart = false;
    let failed = false;
    let that = this;
    switch (event.getEventCode()) {
        case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
            this.tips.string = '未检测到更新插件,跳过更新';
            failed = true;
            break;
        case jsb.EventAssetsManager.UPDATE_PROGRESSION:
            if (event.getPercent()) {
                this.progressBar.progress = Number(event.getPercent());
                this.progress.string = Math.ceil(Number(event.getPercent() * 100)) + "%";
                this.bytes.string = Math.ceil(event.getDownloadedBytes() / 1000) + "K / " + Math.ceil(event.getTotalBytes() / 1000) + "K";
                this.files.string = event.getDownloadedFiles() + " / " + event.getTotalFiles();
            }
            let msg = event.getMessage();
            if (msg) {
                this.tips.string = '下载文件: ' + msg;
            } else {
                let tips = this.tips.string;
                if (tips.length === 8) {
                    tips = "下载文件中.";
                } else if (tips.length === 6) {
                    tips = "下载文件中..";
                } else if (tips.length === 7) {
                    tips = "下载文件中...";
                }
                this.tips.string = tips;
            }
            break;
        case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
        case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
            this.tips.string = '下载manifest文件失败,跳过更新';
            failed = true;
            break;
        case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
            this.tips.string = '已更新到最新版本';
            failed = true;
            break;
        case jsb.EventAssetsManager.UPDATE_FINISHED:
            this.tips.string = '更新完成 ' + event.getMessage();
            this.progressBar.progress = 1;
            this.progress.string = "100%";
            needRestart = true;
            break;
        case jsb.EventAssetsManager.UPDATE_FAILED:
            this.tips.string = '更新失败 ' + event.getMessage();
            this._failCount++;
            let message = this._failCount + "个文件更新失败,请尝试重新下载更新";
            this.confirm(message, function () {
                that.tips.string = '尝试重新加载失败的资源...';
                that.downloadFailedAssets();
            }, function () {
                that.showLoginView();
            });
            break;
        case jsb.EventAssetsManager.ERROR_UPDATING:
            this._failCount++;
            this.tips.string = '更新资源时发生错误: ' + event.getAssetId() + ', ' + event.getMessage();
            break;
        case jsb.EventAssetsManager.ERROR_DECOMPRESS:
            this._failCount++;
            this.tips.string = event.getMessage();
            break;
        default:
            break;
    }
    console.log(this.tips.string);

    if (failed) {
        this.onFailed();
    }

    if (needRestart) {
        this.restart();
    }
},
onFailed() {
    this._am.setEventCallback(null);
    //直接跳转登录界面
    this.showLoginView();
},
restart() {
    this._am.setEventCallback(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.
    cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
    jsb.fileUtils.setSearchPaths(searchPaths);

    cc.audioEngine.stopAll();
    cc.game.restart();
},
//检查原生app的版本号,如果有重新更新安装,则删除旧的热更新资源
checkNativeVersion(noNeedRestart) {
    let io = require("IOUtils");
    let curVersion = cc.beimi.wechat.getNativeAppVersion();
    let preVersion = io.get("appVersion");
    console.log(curVersion, preVersion);
    if (curVersion && preVersion) {
        //如果新版本大于旧版本
        if (Number(curVersion) > Number(preVersion)) {
            //删除热更新资源
            this.clearResourcesAndRestart(noNeedRestart);
        }
    }
    io.put("appVersion", curVersion);
},
clearResourcesAndRestart (noNeedRestart) {
    this.clearHotupdateCache();
    this.clearHotupdateCacheTemp();
    if (!noNeedRestart) {
        cc.audioEngine.stopAll();
        cc.game.restart();
    }
},
/**
 * 一键修复并重启
 */
oneButtonRepaired() {
    if (!cc.sys.isNative) {
        this.msg("仅支持原生平台");
        return;
    }
    let that = this;
    this.confirm("一键修复可以解决无法更新成功或异常出现的未知问题,但可能需要消耗几分钟时间,确定进行此操作?", function () {
        that.clearResourcesAndRestart(false);
    });
},
/**
 * 错误处理和失败重试
 */
downloadFailedAssets() {
    console.log('downloadFailedAssets');
    this._failCount = 0;
    this._am.setEventCallback(this.updateCb.bind(this));
    this._am.downloadFailedAssets();
},
checkUpdate: function () {
    this.tips.string = "检查更新...";
    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);
    }
    if (!this._am.getLocalManifest() || !this._am.getLocalManifest().isLoaded()) {
        this.tips.string = '加载 manifest 失败 ...';
        return;
    }
    this._am.setEventCallback(this.checkCb.bind(this));

    this._am.checkUpdate();
},

hotUpdate: function () {
    console.log("开始热更新");
    if (this._am) {
        console.log("设置热更新回调");
        this._am.setEventCallback(this.updateCb.bind(this));

        if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
            // Resolve md5 url
            let url = this.manifestUrl.nativeUrl;
            if (cc.loader.md5Pipe) {
                url = cc.loader.md5Pipe.transformURL(url);
            }
            this._am.loadLocalManifest(url);
        }

        this._failCount = 0;
        console.log("执行热更新update操作");
        this._am.update();
    }
},
initView() {
    this.tips.string = "";
    this.progressBar.progress = 0;
    this.progress.string = "0%";


    this.desc.active = false;
    this.updateTips.active = false;
    this.main.active = false;

    this.version.active = true;
    this.logo.active = true;
    this.progressBarNode.active = true;
},
// use this for initialization
onLoad: function () {
    // Hot update is only available in Native build
    if (!cc.sys.isNative) {
        return;
    }
    //初始化进入登录页展示的界面
    this.initView();

    this._storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + this._hotUpdateName);
    console.log('Storage path for remote asset : ' + this._storagePath);

    //如果是重新进入游戏,清除cache
    this.clearHotupdateCacheTemp();

    let that = this;
    // 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, versionB) {
        console.log("JS Custom Version Compare: version A is " + versionA + ', version B is ' + versionB);
        that.curVersion.string = versionA;
        that.lastVersion.string = versionB;
        let vA = versionA.split('.');

        let vB = versionB.split('.');
        for (let i = 0; i < vA.length; ++i) {
            let a = parseInt(vA[i]);
            let 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.manifestUrl, this._storagePath, this.versionCompareHandle);

    // 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, asset) {
        // 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) {
            // that.tips.string = "校验文件: " + relativePath;
            console.log("压缩文件,无需校验:" + relativePath);
            return true;
        } else {
            const md5 = that.calMD5OfFile(path);
            // const md5 = crypto.createHash('md5').update(fs.readFileSync(path)).digest('hex');
            that.tips.string = "校验文件: " + relativePath + ' (' + expectedMD5 + ')';
            console.log("热更新文件md校验:左边是服务器上得md5,右边是下载下来后生成得md5码", md5, asset.md5, asset.md5 === md5);
            if (expectedMD5 === md5) {
                return true;
            }
            //md5不相同,删除下载文件
            if (jsb.fileUtils.isFileExist(path)) {
                console.log("文件存在,删除该文件");
                jsb.fileUtils.removeFile(path);
            }
            //返回false,重新下载
            return false;
        }
    });

    this.tips.string = '更新已备就绪,马上开始';

    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(3);
        this.tips.string = "最大下载线程已设置为3";
    }

    //自动检查是否需要更新
    this.checkUpdate();
},
calMD5OfFile(filePath) {
    return MD5(jsb.fileUtils.getDataFromFile(filePath));
},
//清除热更新文件
clearHotupdateCache() {
    if (cc.sys.isBrowser) {
        return;
    }
    let storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + this._hotUpdateName);
    jsb.fileUtils.removeDirectory(storagePath);
},
//清除临时热更新文件
clearHotupdateCacheTemp() {
    if (cc.sys.isBrowser) {
        return;
    }
    console.log('temp file clear');
    let storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + this._hotUpdateName + '_temp');
    jsb.fileUtils.removeDirectory(storagePath);
},
onDestroy: function () {
    if (this._updateListener) {
        this._am.setEventCallback(null);
        this._updateListener = null;
    }
}

});

//如果是重新进入游戏,清除cache
this.clearHotupdateCacheTemp();

我会在每次重启的时候去清空临时缓存文件夹

//清除临时热更新文件
clearHotupdateCacheTemp() {
if (cc.sys.isBrowser) {
return;
}
console.log(‘temp file clear’);
let storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : ‘/’) + this._hotUpdateName + ‘_temp’);
jsb.fileUtils.removeDirectory(storagePath);
},

难道是我的路径写的有问题:
_hotUpdateName: ‘zpsuoha-remote-asset’

我自己定义了个文件夹名

现在的问题是,更新完成后调用cc.game.restart()进入游戏是没有问题的,资源都引用正常;
但是只要我重新后台关闭应用,再打开就会出现资源找不到的问题

安卓调试报错
找不到res/import/uuid.json

都是热更新的资源

找到问题原因了,是hotUpdate插件引入问题,忘记加文件夹,导致构建时没有自动给main.js加上路径

抱歉挖个坟 我也碰到这个问题了 请问是怎么解决的 加文件夹是什么意思?