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

相关推荐
天才熊猫君5 分钟前
配置与数据分离:一种可视化搭建的属性编辑方案
前端·javascript
林希_Rachel_傻希希15 分钟前
web性能之相关路径——AI总结
前端·javascript·面试
不好听61318 分钟前
从零搭建一个 RAG 语义搜索系统 —— DEMO的初始阶段
javascript·面试·llm
何时梦醒22 分钟前
上下文工程(Context Engineering):AI 应用开发的新范式 —— 从理论到实战全解析
javascript
竹林81823 分钟前
用 wagmi v2 踩坑两天,我终于搞懂了多链钱包切换在 DeFi 前端中的正确姿势
前端·javascript
用户21366100357225 分钟前
Vue项目搜索功能与面包屑导航
前端·javascript
星栈29 分钟前
LiveView 的实时通信,爽是爽,但 PubSub 和广播也最容易把自己绕晕
前端·前端框架·elixir
用户29307509766930 分钟前
告别关键词匹配,拥抱向量语义 —— RAG 搜索从零到一
前端
独孤留白39 分钟前
从C到Rust:告别 C 的"指针 + 长度"手动模式
前端·rust
阿黎梨梨1 小时前
揭秘大语言模型的底层逻辑:从文本分词到高维向量的计算之旅
javascript·人工智能