无需重新安装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。这不仅提升了用户体验,也降低了应用的维护成本。

相关推荐
kyriewen118 小时前
你点的“刷新”是假刷新?前端路由的瞒天过海术
开发语言·前端·javascript·ecmascript·html5
摇滚侠9 小时前
JAVA 项目教程《苍穹外卖-12》,微信小程序项目,前后端分离,从开发到部署
java·开发语言·vue.js·node.js
Timer@9 小时前
LangChain 教程 04|Agent 详解:让 AI 学会“自己干活“
javascript·人工智能·langchain
阿珊和她的猫9 小时前
TypeScript中的never类型: 深入理解never类型的使用场景和特点
javascript·typescript·状态模式
skywalk816310 小时前
Kotti Next的tinyfrontend前端模仿Kotti 首页布局还是不太好看,感觉比Kotti差一点
前端
RopenYuan11 小时前
FastAPI -API Router的应用
前端·网络·python
走粥12 小时前
clsx和twMerge解决CSS类名冲突问题
前端·css
Purgatory00112 小时前
layui select重新渲染
前端·layui
weixin1997010801613 小时前
《中国供应商商品详情页前端性能优化实战》
前端·性能优化