## 热更新 * 完全使用creator官方的热更新方案 * 重新封装,使用更简单 * **支持动态变更资源路径** * cdn上资源结构 ![image_hotupdate1](../image/image_hotupdate1.jpeg#pic_left) ### 规则 * 和版本号绑定,版本更新后之前的热更新资源失效,(版本号指的是初始化函数中传入的版本号 推荐使用游戏版本号) * 在构建完成之后的main.js中添加以下内容,可以使用构建模版,或者用脚本修改 ```javascript (function () { if (typeof window.jsb === 'object') { let saveVersion = localStorage.getItem('hotupdate::version'); let searchPaths = localStorage.getItem('hotupdate::searchpaths'); //TODO::版本号 这里需要根据自己的项目修改 let version = "0.0.2"; if (!saveVersion || saveVersion != version ) { localStorage.setItem('hotupdate::searchpaths', null); searchPaths = null; } if (searchPaths) { let paths = JSON.parse(searchPaths); jsb.fileUtils.setSearchPaths(paths); let fileList = []; let storagePath = paths[0] || ''; let tempPath = storagePath + '_temp/'; let baseOffset = tempPath.length; if (jsb.fileUtils.isDirectoryExist(tempPath) && !jsb.fileUtils.isFileExist(tempPath + 'project.manifest.temp')) { jsb.fileUtils.listFilesRecursively(tempPath, fileList); fileList.forEach(srcPath => { let relativePath = srcPath.substr(baseOffset); let dstPath = storagePath + relativePath; if (srcPath[srcPath.length] == '/') { jsb.fileUtils.createDirectory(dstPath); } else { if (jsb.fileUtils.isFileExist(dstPath)) { jsb.fileUtils.removeFile(dstPath); } jsb.fileUtils.renameFile(srcPath, dstPath); } }) jsb.fileUtils.removeDirectory(tempPath); } } } })(); ``` ### 使用 一些枚举类型 ```typescript export enum HotUpdateCode { /** 成功 */ Succeed = 0, /** 平台不支持 不需要热更新 */ PlatformNotSupported = -1000, /** 未初始化 */ NotInitialized = -1001, /** 是最新版本 */ LatestVersion = -1002, /** 更新中 */ Updating = -1003, /** 加载本地manifest失败 */ LoadManifestFailed = -1004, /** 下载manifest文件失败 */ ParseManifestFailed = -1005, /** 下载version.manifest失败 */ LoadVersionFailed = -1006, /** 解析version.manifest失败 */ ParseVersionFailed = -1007, /** 更新失败 需要重试 */ UpdateFailed = -1008, /** 更新错误 */ UpdateError = -1009, /** 解压错误 */ DecompressError = -1010, } ``` * 初始化 【必须】 ```typescript /** * 初始化热更新管理器 * @param manifestUrl 传入本地manifest文件地址 creator资源Asset下的属性nativeUrl * @param version 游戏版本号 eg: 1.0.0 */ kunpocc.HotUpdateManager.getInstance().init(manifestUrl: string, version: string) ``` * 检查更新 ```typescript interface ICheckResult { /** 0:成功 其他:失败 */ code: number; /** 失败信息 */ message: string;; /** 需要更新的资源大小 (KB) */ size?: number; } kunpo.HotUpdateManager.getInstance().checkUpdate().then((res: ICheckResult) => { console.log(`发现更新 资源大小:${res.size}kb`); // 直接更新 // this.startUpdate(true); }).catch((err: any) => { log("检查热更新出错了", JSON.stringify(err)); if (res.code == HotUpdateCode.LatestVersion) { console.log(`已经是最新版本了`); } else { console.log(`出错了 code:${res.code} message:${res.message}`); // 根据 HotUpdateCode 中的错误码, 做后续处理,或提示,或跳过本次更新等 } }); ``` * 直接尝试更新 ```typescript kunpo.HotUpdateManager.getInstance().startUpdate({ skipCheck: skipCheck, // 是否跳过检查更新,如果没有提前使用 progress: (kb: number, total: number) => { kunpo.log("热更新进度", kb, total); }, complete: (code: HotUpdateCode, message: string) => { kunpo.log("热更新成功或者失败了", code, message); if (code == HotUpdateCode.LatestVersion) { console.log(`已经是最新版了`); } else if (code == HotUpdateCode.UpdateFailed) { console.log(`更新失败了 code:${code} message:${message}`); // 可以在这里重试失败的资源 // kunpo.HotUpdateManager.getInstance().retryUpdate(); } else if (code == HotUpdateCode.LoadVersionFailed || code == HotUpdateCode.ParseVersionFailed) { console.log(`更新失败了 可以选择跳过热更新 code:${code} message:${message}`); } else { console.log(`其他的失败 code:${code} message:${message}`); } } }); ```