uni-app自动更新核心是严格分离热更新(wgt)与整包更新(apk/ipa):热更新需用plus.runtime.install()配合https wgt包及plus.runtime.restart(),整包更新android须uni.downloadfile+uni.installapp()并申请request_install_packages权限,ios仅能跳转app store或itms-services链接;版本比对必须用plus.runtime.version(需plus.ready就绪后获取)并逐段数字比较,禁用字符串直接比较。

uni-app 实现自动更新 App 版本,核心不是“能不能做”,而是「热更新(wgt)和整包更新(APK/IPA)必须严格分离、各自走对路径」。用错接口、传错路径、比错版本号,都会导致静默失败——连错误回调都没有。
怎么正确获取并比对当前 App 版本号
别用 uni.getSystemInfoSync().version,它在 Android 上常为空,iOS 上返回的是系统版本;真正可靠的是 plus.runtime.version,但它只在 5+ App 环境可用,且必须等 plus.ready 就绪后才能读取。
- 冷启动时直接在
onLaunch里读plus.runtime.version,大概率拿到空字符串或undefined - 必须包裹
plus.ready(() => { const currentVersion = plus.runtime.version }),否则后续所有比对都无效 - 服务端返回的版本字段(如
"1.10.0")必须是纯数字点分格式,禁用"v1.10.0"、"1.10.0-beta"、前导零等写法 - 字符串字典序比较会翻车:
"1.9.0" > "1.10.0"返回true,但语义上是错的;必须拆成数组逐段转Number比对,或直接用 HBuilderX 3.1.22+ 内置的uni.compareVersion(a, b)
plus.runtime.install() 调了没反应的常见原因
plus.runtime.install() 是 wgt 热更新的核心,但它极其敏感,任何一环出错都会静默失败:
- URL 不是 HTTPS 直链,或服务端返回状态码不是 200,或
Content-Type不是application/octet-stream - 本地
manifest.json的versionName没变:必须先改它,再通过 HBuilderX → 发行 → 原生App → 制作移动App资源升级包 生成新 wgt;手动 zip 压缩、漏改versionCode都会导致失败 - 没等
plus.ready就调用,或安装后没显式调用plus.runtime.restart(),旧代码仍在运行 - 验证方式错误:不要只看下载完成,要安装后立刻查
plus.runtime.getProperty('version'),值变了才算真生效
Android uni.installApp() 总失败怎么办
uni.installApp() 在 Android 上不是“传个 URL 就装”,必须手动处理下载 + 权限 + 路径三步:
- 不能传远程 URL:必须先用
uni.downloadFile()下载到本地,取tempFilePath再传给uni.installApp() - 路径必须可读:推荐保存到
uni.env.USER_DATA_PATH + '/update/app-release.apk',避免 Android 10+ 外部存储限制 - Android 8+ 必须申请
REQUEST_INSTALL_PACKAGES权限:manifest.json → 模块配置 → 勾选「Native.js 权限」→ 启用该权限;首次安装前还需主动调用plus.android.requestPermissions(['android.permission.REQUEST_INSTALL_PACKAGES']) - H5 和小程序端不支持该 API,必须用
#ifdef APP条件编译屏蔽
iOS 整包更新只能跳转,无法静默安装
iOS 完全没有“应用内安装 APK”这回事,uni.installApp() 在 iOS 上实际行为是跳转:
- 若传入的是 plist 地址,尝试用
itms-services://?action=download-manifest&url=协议打开(需企业签名或 TestFlight) - 若失败或非企业环境,则 fallback 到 Safari 打开 App Store 页面,拼接
https://apps.apple.com/app/id{appid} - plist 文件必须部署在 HTTPS 域名下,且服务器需配置正确 MIME 类型和 CORS
- 别指望监听安装结果——iOS 不提供任何回调,用户是否安装、装没装成功,前端完全不可知
最易被忽略的一点:H5 和小程序端根本不存在“安装更新”概念,所有相关逻辑必须主动屏蔽;而 Android 上的 INSTALL_FAILED_USER_RESTRICTED 错误,90% 是因为没提前申请权限,不是代码写错了。











