在 uni-app 中,uni.getSystemInfoSync()plus.runtime.getProperty(plus.runtime.appid) 都能获取版本信息,但它们的核心区别在于返回的版本类型不同,这对于实现版本升级至关重要。

简单来说:

  • plus.runtime.getProperty(...): 获取的是 WGT 资源包版本。这是热更新后的实际运行版本。
  • uni.getSystemInfoSync(): 获取的是 App 安装包(基座)版本。这是你从应用商店下载或打包生成的 APK/IPA 文件的版本。

🔍 详细区别与对比

为了更清晰地理解,我们可以通过一个表格来对比:

特性 plus.runtime.getProperty(plus.runtime.appid) uni.getSystemInfoSync()
获取方式 异步方法调用 同步方法调用
版本类型 WGT 资源包版本 (当前运行的 js 代码版本) App 安装包/基座版本 (原生壳版本)
主要用途 热更新(资源在线升级)的版本比对 判断是否需要整包更新、区分平台等
更新后变化 热更新后会立即变为新版本号 只有重新安装 App 才会改变
执行时机 需要在回调函数中获取数据 立即返回结果

💡 如何选择用于版本升级?

选择哪个方法取决于你的更新策略。在实际项目中,通常会将两者结合使用,以支持两种更新模式:热更新(增量更新)整包更新(强制更新)

场景一:热更新 (WGT Update)

如果你的更新不涉及原生插件的增删改,只是修改了前端页面、样式或 JS 逻辑,那么应该使用热更新。

  • 应使用: plus.runtime.getProperty(plus.runtime.appid, ...)
  • 原因: 你需要获取用户手机上当前正在运行的 WGT 包的版本号,然后与你服务器上的最新版本号进行比对。如果服务器版本更高,则下载并安装新的 WGT 包。
  • 关键点: 安装成功后,必须调用 plus.runtime.restart() 重启 App,新版本才能生效。

场景二:整包更新 (Store Update)

如果你的更新涉及原生功能(如新增地图模块、修改原生插件),或者你希望引导用户去应用商店下载最新版,则需要整包更新。

  • 应使用: uni.getSystemInfoSync().appVersionplus.runtime.version
  • 原因: 这两种方式获取的都是 App 安装包的版本。你可以用这个版本号去和你的服务器比对,如果发现有大版本更新,就弹窗提示用户前往应用商店(Android)或 App Store(iOS)进行更新。

📝 实践建议与代码示例

一个健壮的版本更新检测逻辑通常会融合这两种方式。服务端会根据客户端上报的版本信息,判断是返回 WGT 更新包还是引导去应用商店。

以下是一个简化的实现思路:

  1. // 在 App.vue 的 onLaunch 生命周期中进行检测
  2. onLaunch() {
  3. // #ifdef APP-PLUS
  4. // 1. 首先获取 WGT 包版本,用于热更新检测
  5. plus.runtime.getProperty(plus.runtime.appid, (widgetInfo) => {
  6. const currentWgtVersion = widgetInfo.version; // 例如 "1.0.5"
  7. // 2. 同时获取 App 安装包版本,备用
  8. const appInstallVersion = plus.runtime.version; // 例如 "1.1.0"
  9. // 3. 请求服务器,带上两个版本号
  10. uni.request({
  11. url: 'https://your-server.com/api/check-update',
  12. data: {
  13. wgtVersion: currentWgtVersion,
  14. appVersion: appInstallVersion,
  15. platform: uni.getSystemInfoSync().platform // 'android' or 'ios'
  16. },
  17. success: (res) => {
  18. const updateInfo = res.data;
  19. if (updateInfo.type === 'wgt') {
  20. // --- 处理热更新 ---
  21. console.log('发现资源更新,开始下载...');
  22. this.doWgtUpdate(updateInfo.wgtUrl);
  23. } else if (updateInfo.type === 'store') {
  24. // --- 处理整包更新 ---
  25. console.log('发现重要更新,请前往应用商店更新');
  26. this.showStoreUpdateModal(updateInfo.storeUrl);
  27. }
  28. }
  29. });
  30. });
  31. // #endif
  32. },
  33. methods: {
  34. // 执行 WGT 更新
  35. doWgtUpdate(wgtUrl) {
  36. uni.downloadFile({
  37. url: wgtUrl,
  38. success: (downloadResult) => {
  39. if (downloadResult.statusCode === 200) {
  40. plus.runtime.install(downloadResult.tempFilePath, {}, () => {
  41. console.log('WGT 安装成功');
  42. // 【关键步骤】重启应用使更新生效
  43. plus.runtime.restart();
  44. }, (e) => {
  45. console.error('WGT 安装失败', e);
  46. });
  47. }
  48. }
  49. });
  50. },
  51. // 显示去应用商店更新的弹窗
  52. showStoreUpdateModal(storeUrl) {
  53. uni.showModal({
  54. title: '版本更新',
  55. content: '发现新版本,请前往应用商店更新以获得最佳体验。',
  56. confirmText: '去更新',
  57. success: (res) => {
  58. if (res.confirm) {
  59. plus.runtime.openURL(storeUrl);
  60. }
  61. }
  62. });
  63. }
  64. }

⚠️ 特别注意事项

  1. 鸿蒙平台 (HarmonyOS)

    • 对于鸿蒙应用,推荐使用跨平台 API uni.getAppBaseInfo()uni.getSystemInfo() 来获取版本信息,而不是 plus 相关的方法,因为鸿蒙可能不完全支持 app-plus 模块。
    • uni.getAppBaseInfo() 会返回 appVersion (版本名称) 和 appVersionCode (版本号),这两个值对应 manifest.json 中的配置。
  2. 测试环境

    • 在 HBuilderX 真机运行模式下,获取到的版本信息是 HBuilder 基座应用的,而非你自己的应用。因此,版本更新功能必须在打包成自定义基座或正式包后进行测试。
  3. 不要混淆

    • 切勿使用 plus.runtime.version 来判断是否需要热更新,因为它获取的是安装包版本,不会随 WGT 更新而改变。