无需重新安装APK | uni-app 热更新技术实战

前言

在移动应用开发中,频繁的版本更新是不可避免的。传统的更新方式需要用户重新下载安装 APK,这不仅用户体验差,而且会增加用户流失率。

问题:

在最近项目中,由于上线到应用商城时间长且繁琐,加上该项目的用户群体是面向农田人员,不是大众应用,其实可以不上线。但是不上线,怎么解决前端代码修改后,用户不需要安装新版本的apk就可以更新呢?

解决方案

可以在 uni-app 中实现热更新功能,让前端代码的修改能够直接更新到用户的应用中。

热更新原理:

热更新是指应用在运行时下载并安装更新包,无需重新安装整个应用即可应用新的代码和资源。在 uni-app 中,热更新主要通过以下步骤实现:

  1. 检查应用当前版本号

  2. 从服务器获取最新版本信息

  3. 比较版本号,判断是否需要更新

  4. 如果需要更新,下载热更新包(.wgt 文件)

  5. 安装热更新包

  6. 重启应用以应用新代码

实现过程:

在 uni-app 项目中,热更新的核心逻辑通常放在 App.vue 文件中,在应用启动时触发更新检查。

  1. 生命周期钩子
javascript 复制代码
// 生命周期钩子
onLaunch(() => {
  checkUpdate();
});

onShow(() => {
  // console.log("App Show");
});

onHide(() => {
  // console.log("App Hide");
});

2.版本号比较方法

我这里获取的版本模板是:v1.0.0这种,所以需要进行匹配比较

javascript 复制代码
// 版本号比较方法
const compareVersion = (version1, version2) => {
  const arr1 = version1.split('.');
  const arr2 = version2.split('.');
  const length1 = arr1.length;
  const length2 = arr2.length;
  const minlength = Math.min(length1, length2);
  let i = 0;
  for (; i < minlength; i++) {
    const a = parseInt(arr1[i]);
    const b = parseInt(arr2[i]);
    if (a > b) {
      return 1;
    } else if (a < b) {
      return -1;
    }
  }
  if (length1 > length2) {
    for (let j = i; j < length1; j++) {
      if (parseInt(arr1[j]) != 0) {
        return 1;
      }
    }
    return 0;
  } else if (length1 < length2) {
    for (let j = i; j < length2; j++) {
      if (parseInt(arr2[j]) != 0) {
        return -1;
      }
    }
    return 0;
  }
  return 0;
};
  1. 下载并安装 WGT 包

此方法负责下载热更新包,并显示下载进度。下载成功后,调用 `installWgt` 方法安装更新包。

javascript 复制代码
// 下载并安装 WGT 包
const downloadAndInstall = (downloadPath) => {
  const downloadTask = uni.downloadFile({
    url: downloadPath,
    success: (res) => {
      if (res.statusCode === 200) {
        installWgt(res.tempFilePath);
      }
    },
    fail: (error) => {
      console.error('下载失败:', error);
      uni.hideLoading();
      uni.showToast({ title: '下载失败', icon: 'none' });
    }
  });
  downloadTask.onProgressUpdate((res) => {
    uni.showLoading({
      title: `下载中 ${res.progress}%`,
      mask: true
    });
  });
};
  1. 安装 WGT 包

此方法使用 `plus.runtime.install` 安装热更新包,安装成功后重启应用以应用新代码。

javascript 复制代码
// 安装 WGT 包
const installWgt = (wgtPath) => {
  // 使用 plus.runtime.install 安装 wgt 包
  plus.runtime.install(
    wgtPath,
    {
      force: true // false 表示会校验版本号(必须新版本 > 当前版本),true 强制安装
    },
    () => {
      // 安装成功
      uni.hideLoading();
      uni.showToast({ title: '更新成功', icon: 'none' });
      
      // 延迟 1 秒后重启(给用户看到提示)
      setTimeout(() => {
        plus.runtime.restart(); // 重启 App,使新代码生效
      }, 2000);
    },
    (e) => {
      // 安装失败
      uni.hideLoading();
      console.error('WGT 安装失败:', e);
      uni.showToast({
        title: '更新失败,请重试',
        icon: 'none',
        duration: 3000
      });
    }
  );
};
  1. 检查更新

此方法是热更新的核心逻辑,主要步骤包括:

  1. 检查是否在 App 环境下(热更新只在 App 环境下可用)

  2. 获取当前应用版本号

  3. 调用接口获取最新热更新包信息

  4. 比较版本号,判断是否需要更新

  5. 如果需要更新,显示更新提示,用户确认后下载并安装更新包

javascript 复制代码
// 检查更新
const checkUpdate = async () => {
  try {
    // 检查是否在 H5+ 环境下(热更新只在 App 环境下可用)
    if (typeof plus === 'undefined') {
      console.log('非 App 环境,跳过热更新检查');
      return;
    }

    // 获取当前应用版本号
    const appInfo = uni.getAppBaseInfo();
    const currentVersion = appInfo.appWgtVersion || appInfo.appVersion;

    // 调用接口获取最新热更新包信息
    const res = await getUpdatePackage({ platform: 'Mobile' });
    if (res.code === 0 && res.data) {
      const latestVersion = res.data.version.replace('v', '');
      const downloadPath = res.data.downloadPath;

      // 比较版本号
      if (compareVersion(latestVersion, currentVersion) > 0) {
        // 显示更新提示
        uni.showModal({
          title: '版本更新',
          content: `当前版本:${currentVersion}\n最新版本:${latestVersion}\n是否立即更新?`,
          confirmText: '立即更新',
          cancelText: '暂不更新',
          success: (modalRes) => {
            if (modalRes.confirm) {
              downloadAndInstall(downloadPath);
            }
          }
        });
      }
    }
  } catch (error) {
    console.error('检查更新失败:', error);
  }
};

热更新包的生成:

在 uni-app 中,热更新包是通过 HBuilderX 生成的。具体步骤如下:

  1. 在 HBuilderX 中打开项目

  2. 点击菜单栏的「发行」

  1. 记得先填写更新版本号,点击「确认」按钮
  1. 生成的 .wgt 文件就是热更新包

总结

通过以上实现,我们可以在 uni-app 中实现热更新功能,让前端代码的修改能够直接更新到用户的应用中,无需用户重新安装 APK。这不仅提升了用户体验,也降低了应用的维护成本。

相关推荐
遇见小美好y2 小时前
uniapp 实现向下追加数据功能
前端·javascript·uni-app
wuhen_n2 小时前
数据缓存策略:让我们的应用“快如闪电”
前端·javascript·vue.js
wuhen_n2 小时前
自定义指令:为 DOM 操作提供高效的抽象入口
前端·javascript·vue.js
C_心欲无痕2 小时前
前端 PDF 渲染与下载实现
前端·pdf
jiayong232 小时前
可视化流程设计器技术对比:钉钉风格 vs BPMN
java·前端·钉钉
前端不太难2 小时前
Flutter Web / Desktop 为什么“能跑但不好用”?
前端·flutter·状态模式
甘露s2 小时前
新手入门:传统 Web 开发与前后端分离开发的区别
开发语言·前端·后端·web
双河子思2 小时前
自动化控制逻辑建模方法
前端·数据库·自动化
wsad05322 小时前
Vue.js 整合传统 HTML 项目:注册页面实战教程
前端·vue.js·html