前言
在移动应用开发中,频繁的版本更新是不可避免的。传统的更新方式需要用户重新下载安装 APK,这不仅用户体验差,而且会增加用户流失率。
问题:
在最近项目中,由于上线到应用商城时间长且繁琐,加上该项目的用户群体是面向农田人员,不是大众应用,其实可以不上线。但是不上线,怎么解决前端代码修改后,用户不需要安装新版本的apk就可以更新呢?
解决方案
可以在 uni-app 中实现热更新功能,让前端代码的修改能够直接更新到用户的应用中。
热更新原理:
热更新是指应用在运行时下载并安装更新包,无需重新安装整个应用即可应用新的代码和资源。在 uni-app 中,热更新主要通过以下步骤实现:
-
检查应用当前版本号
-
从服务器获取最新版本信息
-
比较版本号,判断是否需要更新
-
如果需要更新,下载热更新包(.wgt 文件)
-
安装热更新包
-
重启应用以应用新代码
实现过程:
在 uni-app 项目中,热更新的核心逻辑通常放在 App.vue 文件中,在应用启动时触发更新检查。
- 生命周期钩子
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;
};
- 下载并安装 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
});
});
};
- 安装 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
});
}
);
};
- 检查更新
此方法是热更新的核心逻辑,主要步骤包括:
-
检查是否在 App 环境下(热更新只在 App 环境下可用)
-
获取当前应用版本号
-
调用接口获取最新热更新包信息
-
比较版本号,判断是否需要更新
-
如果需要更新,显示更新提示,用户确认后下载并安装更新包
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 生成的。具体步骤如下:
-
在 HBuilderX 中打开项目
-
点击菜单栏的「发行」

- 记得先填写更新版本号,点击「确认」按钮


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