bit-hotupdate:热更新流程封装好,剩下的只是接几个回调

它解决什么问题

Cocos Creator 官方提供了热更新的底层能力,但直接用原生 API 意味着你要自己处理 manifest 文件解析、版本比较、下载状态机、各种失败重试的分支——业务代码想接一个”检查更新→提示用户→下载→重启”的标准流程,中间要写不少胶水代码,而且这块逻辑一旦写错很容易导致玩家更新失败甚至卡死在更新界面出不去。

bit-hotupdate 把这套状态机封装好,业务层只需要接几个回调,不用关心底层怎么解析 manifest、怎么算增量。

安装

bit-corebit-net 是 peer 依赖:

npm install @gongxh/bit-hotupdate @gongxh/bit-core @gongxh/bit-net

核心用法

初始化(游戏启动时调一次)

import { HotUpdateManager } from '@gongxh/bit-hotupdate';

const hotUpdate = HotUpdateManager.getInstance();
hotUpdate.init(manifestUrl, '1.0.0.23'); // 版本号带 build 号

检查更新

try {
    const result = await hotUpdate.checkUpdate();
    if (result.needUpdate) {
        console.log(`需要更新,大小约 ${result.size}KB`);
        // 弹窗提示用户,用户确认后再调 startUpdate
    }
} catch (e) {
    console.log('检查更新失败', e);
}

checkUpdate 失败会直接 throw(比如还没初始化,或者正在更新/检查中),一定要 try/catch 包起来,不然会变成未捕获异常。

开始更新

hotUpdate.startUpdate({
    progress: (downloadedKB, totalKB) => {
        progressBar.value = downloadedKB / totalKB;
    },
    complete: (code, message) => {
        if (code === HotUpdateCode.WaitRetry) {
            // 单次下载失败,可以重试
            hotUpdate.retryUpdate();
        } else if (code === HotUpdateCode.UpdateError) {
            // 不可恢复的错误,提示玩家重启游戏重新走一次流程
        }
    },
});

有个反直觉的地方要注意:更新成功不会走 complete 回调,因为更新完成后游戏会自动重启,complete 只用来通知你”这次没成功,出了什么问题”。

状态码怎么用

HotUpdateCode 覆盖了几种典型场景:

  • LatestVersion(-1001)—— 已是最新版本,或者当前平台本来就不需要热更新(比如小游戏平台走的是另一套更新机制)
  • Updating(-1002)—— 正在更新或检查中,重复调用会拿到这个
  • WaitRetry(-1003)—— 单次下载失败,调 retryUpdate() 就行,不用重新走 checkUpdate
  • UpdateError(-1004)—— 不可恢复的错误(包括解压失败),一般得重启游戏
  • CheckError(-1005)—— 检查阶段出错(读本地/远程 manifest 失败),具体看 message

Manifest 文件和服务端要点

热更新要维护两个文件:project.manifest(完整资源清单,含每个文件的 MD5 和大小,用来算增量)和 version.manifest(只有版本信息的轻量文件,用来快速检查有没有新版本,不用下载整个清单)。

服务端配置上有几个容易漏掉的点:跨域要允许manifest 文件不能被缓存(不然玩家永远查不到新版本),要支持 Range 请求(断点续传要靠这个)。这几个配置项漏了任何一个,热更新表现出来的症状可能是”偶尔更新不了”或者”更新进度卡住不动”,排查起来容易先怀疑到客户端代码上。

避坑提醒

  • checkUpdate 抛异常的场景(未初始化、正在更新中)一定要 catch,业务层直接崩溃比更新失败体验更差。
  • 更新成功游戏会自动重启,别在 complete 回调里写”更新成功后要做的事”,这段回调根本不会被触发。
  • 目前只支持 Android 和 iOS 原生平台,小游戏平台不走这套流程(它们有自己的资源版本机制),代码里如果做了平台判断,别忘了在非原生平台跳过热更新调用。

项目信息

底层网络请求靠 bit-net,平台信息判断靠 bit-core,三个模块配合着用。