热更新失败主因是 manifest.json 中 versioncode 非递增正整数或 appid 与原包不一致;wgt 包须由 hbuilderx“制作移动app资源升级包”生成,且 plus.runtime.install() 必须传入 uni.downloadfile() 下载后的合法本地路径。

manifest.json 的 versionCode 和 appid 必须严格匹配
热更新失败最常见原因是 manifest.json 里改了 versionName(比如从 "1.0.1" 改成 "1.0.2"),但漏掉或误改了 versionCode 和 appid。这两个字段才是 plus.runtime.install() 校验的硬门槛:
-
versionCode必须是递增正整数(如101→102),不能带点、不能重复,否则安装时静默失败 -
appid必须和你最初打包上线的 App 完全一致(如"UNI832D722"),错一个字符就会报"Invalid widget package" - HBuilderX 打包 wgt 时会自动读取这两个值,生成文件名形如
UNI832D722_1.0.2.wgt,服务端返回的wgtUrl必须指向这个精确命名的文件
用 HBuilderX 正确生成 wgt 包,不是导出 zip
很多人在「发行」菜单里点了「原生App-云打包」,结果得到的是 apk/ipa——这根本不是热更新需要的资源包。真正要找的是:
- 菜单 → 发行 → 原生App-制作移动App资源升级包(不是「云打包」,也不是「本地打包」)
- 执行后控制台会输出类似:
WGT package generated: /path/to/UNI832D722_1.0.2.wgt - 这个
.wgt文件本质是 zip,但必须由 HBuilderX 按规则生成:它内部包含校验用的widget.xml,且资源路径结构与原 App 一致,手动压缩无效
plus.runtime.install() 调用前必须确保下载完成且路径合法
直接传 URL 给 plus.runtime.install() 是错的。它只接受本地临时路径,所以必须走 uni.downloadFile() 中转:
-
url必须是 HTTPS(iOS 强制;Android 8.0+ 默认拦截 HTTP) - 路径不能含中文、空格或特殊符号,例如
https://example.com/static/UNI832D722_1.0.2.wgt可行,https://example.com/更新包/UNI832D722.wgt会失败 - 下载成功后,必须检查
downloadResult.statusCode === 200,再把downloadResult.tempFilePath传给plus.runtime.install() -
force: false是默认行为,此时versionCode必须严格大于当前值;设为true可跳过校验,但仅用于调试,上线禁用
服务端接口返回字段大小写和结构不能有偏差
客户端靠 res.data.update 和 res.data.wgtUrl 两个字段驱动流程,任何拼写或类型错误都会中断:
- 响应头必须是
Content-Type: application/json - 字段名严格区分大小写:
update(布尔)、wgtUrl(字符串)、pkgUrl(可选),写成Update或wgturl就失效 -
wgtUrl不能为空字符串、null或undefined;哪怕只是多一个空格,plus.runtime.install()都不会触发 - 测试时建议用
curl -v "https://your-api.com/update?version=1.0.1&name=MyApp"直接看原始响应,绕过前端逻辑干扰
最容易被忽略的一点:iOS 上 wgt 更新不会立即生效,必须调用 plus.runtime.restart() 才能加载新资源;而 Android 在 install 成功后即可生效,但部分机型仍需重启才能刷新所有页面。别依赖“下载完就看到变化”这种直觉。











