鸿蒙内置版本升级模块:更新检测、下载、安装适配
应用上线之后,版本迭代是常态。新版本修了bug、加了功能,怎么推给用户?自己做一套更新系统,要搭服务器、存安装包、写下载逻辑、处理断点续传,工作量不小。鸿蒙内置了版本升级模块,从检测更新、下载安装到升级策略,全套能力都提供了,不用自己从头造轮子。
本文基于最新鸿蒙API,把版本升级的完整流程讲清楚:怎么检测新版本、下载进度怎么监听、安装怎么适配,代码可以直接复制到项目里跑。
01 版本升级能力概览
鸿蒙的版本升级能力由@kit.UpgradeKit提供,核心是UpdateClient客户端。它帮你处理了几件事:
-
更新检测:查询当前应用有没有可用的新版本
-
下载安装包:后台下载APK/HAP,支持断点续传
-
状态监听:下载进度、安装状态、错误回调
-
升级策略:强制更新、可选更新、静默升级
底层依赖华为应用市场的升级通道,安装包托管在华为服务器上,不用自己搭文件服务。开发者只需要在AppGallery Connect后台上传新版本,代码里调用接口就能检测和下载。
使用前需要先在module.json5里配置权限:
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"reason": "$string:net_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
网络权限是必须的,检测更新和下载安装包都要联网。
02 更新检测实现
检测更新的核心是调用checkUpdate方法,传入上下文,系统会自动对比当前版本和应用市场上的最新版本。
import { update } from '@kit.UpgradeKit';
import { common } from '@kit.AbilityKit';
async function checkForUpdate(context: common.Context) {
// 创建升级客户端
const updateClient = update.createUpdateClient(context);
// 注册检查结果回调
updateClient.on('eventInfo', (result: update.UpdateResult) => {
console.info('升级检查结果:', result.installState);
// installState: 0=无更新, 1=有新版本
if (result.installState === 1) {
console.info('发现新版本,版本号:', result.versionName);
console.info('版本大小:', result.versionSize);
console.info('更新说明:', result.releaseNotes);
} else {
console.info('已经是最新版本');
}
});
// 发起检测
await updateClient.checkUpdate();
}
检测结果里几个关键字段:
-
installState:0代表没有更新,1代表有新版本
-
versionName:新版本的版本名,比如2.1.0
-
versionSize:安装包大小,单位字节
-
releaseNotes:更新说明,就是后台填的更新日志
检测时机一般选在应用启动后、设置页的"关于我们"里。不要一启动就弹更新提示,用户刚打开APP就被打断体验不好。可以在首页加载完之后静默检测,有更新了再弹提示。
还有一个细节:检测更新是异步的,不要在启动页等检测结果返回再往下走。先让用户进首页,检测完了再弹更新弹窗。
03 下载进度与状态监听
用户确认要更新之后,就开始下载安装包。下载过程中要监听进度,给用户展示下载百分比,不然用户不知道下到哪了,会以为卡了。
import { update } from '@kit.UpgradeKit';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct UpdatePage {
@State downloadProgress: number = 0;
@State isDownloading: boolean = false;
private updateClient: update.UpdateClient | null = null;
// 开始下载
async startDownload(context: common.Context) {
this.updateClient = update.createUpdateClient(context);
this.isDownloading = true;
// 监听下载进度
this.updateClient.on('downloadProgress', (progress: number) => {
this.downloadProgress = progress;
console.info('下载进度:', progress, '%');
});
// 监听下载状态变化
this.updateClient.on('installStatus', (status: update.InstallStatus) => {
console.info('安装状态:', status);
// status: 0=下载中, 1=下载完成, 2=安装中, 3=安装成功, 4=失败
if (status === update.InstallStatus.INSTALL_SUCCESS) {
this.isDownloading = false;
promptAction.showToast({ message: '更新安装完成' });
} else if (status === update.InstallStatus.INSTALL_FAILURE) {
this.isDownloading = false;
promptAction.showToast({ message: '更新失败,请重试' });
}
});
// 发起下载
await this.updateClient.startDownload();
}
build() {
Column() {
Text('版本更新')
.fontSize(20)
.margin({ bottom: 20 })
if (this.isDownloading) {
Text(`下载中... ${this.downloadProgress}%`)
.fontSize(16)
.margin({ bottom: 10 })
Progress({ value: this.downloadProgress, total: 100, type: ProgressType.Linear })
.width('80%')
} else {
Button('立即更新')
.width('60%')
.onClick(() => {
this.startDownload(getContext(this));
})
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
下载进度是百分比数值,0到100,直接绑定到进度条组件上就行。系统会自动处理断点续传,下载中途网络断了,下次打开会接着下,不用自己实现。
还有一个注意点:下载大安装包的时候,建议提示用户在WiFi环境下下载,不然流量费用户会投诉。可以判断当前网络类型,如果是蜂窝网络,先弹个提示确认再开始下载。
04 安装与升级策略
下载完成之后,系统会自动弹出安装界面,用户确认后开始安装。安装过程中应用会退出,安装完成后自动打开新版本。
升级策略有两种,按业务需要选:
可选更新:用户可以选择"稍后再说",不强制升级。大部分普通版本用这种,用户体验好。
强制更新:老版本有严重bug,不升级不能用。这时候用户不更新就退出应用,不能跳过。
async function checkUpdateAndPrompt(context: common.Context) {
const client = update.createUpdateClient(context);
client.on('eventInfo', (result: update.UpdateResult) => {
if (result.installState === 1) {
// 判断是否强制更新,这个标识从服务器配置或者版本标记里来
const isForceUpdate = result.versionCode > 100; // 示例:高于某版本号强制
if (isForceUpdate) {
// 强制更新:弹不可关闭的弹窗
showForceUpdateDialog(context, result);
} else {
// 可选更新:弹可以关闭的弹窗
showOptionalUpdateDialog(context, result);
}
}
});
await client.checkUpdate();
}
// 强制更新弹窗
function showForceUpdateDialog(context: common.Context, info: update.UpdateResult) {
// 自定义弹窗,不允许点击外部关闭
// 内容:有新版本必须更新才能继续使用
// 按钮:只有"立即更新",没有"稍后"
console.info('强制更新弹窗');
}
// 可选更新弹窗
function showOptionalUpdateDialog(context: common.Context, info: update.UpdateResult) {
// 自定义弹窗,可以关闭
// 按钮:"立即更新" 和 "稍后再说"
console.info('可选更新弹窗');
}
强制更新的标识不是升级接口给的,是自己定义的。一般做法是后端返回一个最低支持版本号,当前版本低于这个号就强制更新。或者在AppGallery后台上传版本的时候,标记这个版本是强制升级。
05 完整升级流程封装
把检测、下载、弹窗、策略都封装到一个工具类里,项目里直接调用。
import { update } from '@kit.UpgradeKit';
import { common } from '@kit.AbilityKit';
import { promptAction } from '@kit.ArkUI';
class UpdateManager {
private static instance: UpdateManager;
private updateClient: update.UpdateClient | null = null;
static getInstance(): UpdateManager {
if (!UpdateManager.instance) {
UpdateManager.instance = new UpdateManager();
}
return UpdateManager.instance;
}
// 检查更新,自动弹提示
async checkAndPrompt(context: common.Context) {
this.updateClient = update.createUpdateClient(context);
this.updateClient.on('eventInfo', async (result) => {
if (result.installState !== 1) {
promptAction.showToast({ message: '当前已是最新版本' });
return;
}
// 这里可以根据result判断是强制还是可选
const needForce = result.versionCode >= 200;
if (needForce) {
await this.forceUpdateFlow(result);
} else {
await this.optionalUpdateFlow(result);
}
});
try {
await this.updateClient.checkUpdate();
} catch (e) {
console.error('检查更新失败:', e);
}
}
// 可选更新流程
private async optionalUpdateFlow(result: update.UpdateResult) {
// 弹确认框,用户点确认再下载
console.info('可选更新,用户确认后下载');
// 实际项目里用AlertDialog实现
}
// 强制更新流程
private async forceUpdateFlow(result: update.UpdateResult) {
// 弹不可关闭的弹窗
console.info('强制更新,必须下载安装');
}
// 开始下载
async startDownload() {
if (!this.updateClient) return;
this.updateClient.on('downloadProgress', (progress) => {
console.info('下载进度:', progress);
});
this.updateClient.on('installStatus', (status) => {
if (status === update.InstallStatus.INSTALL_SUCCESS) {
promptAction.showToast({ message: '更新完成' });
}
});
await this.updateClient.startDownload();
}
}
// 使用方式:在EntryAbility的onCreate里调用
// UpdateManager.getInstance().checkAndPrompt(context);
这样封装之后,页面里只需要调一个checkAndPrompt方法,剩下的检测、弹窗、下载逻辑都在内部处理。
落地注意事项
**检测时机要合理。**不要一打开APP就弹更新提示,用户刚进来就被打断体验不好。建议在首页加载完成、用户操作了几秒之后静默检测,有更新再弹。
**大安装包提示WiFi。**安装包超过100M的话,蜂窝网络下下载会耗流量。开始下载前判断一下当前网络,如果是流量,弹个提示问用户要不要继续。
**更新日志要写清楚。**弹更新弹窗的时候,把版本更新说明列出来,用户知道更新了什么才愿意更。不要只写"新版本上线",太敷衍了。
**失败要有重试。**下载失败了不能直接结束,要给用户重试的机会。网络波动很正常,失败点个按钮重新下就行。
小结
鸿蒙内置的版本升级模块,把检测、下载、安装这套流程都封装好了,不用自己搭服务、写断点续传。开发者只需要在AppGallery后台上传新版本,代码里调几个接口就能完成完整的升级流程。
实际项目中,把升级逻辑封装到统一的工具类,检测时机选好,强制和可选策略分清楚,下载进度给用户看明白。用户升级体验好了,新版本的覆盖率自然就上去了。
更多推荐

所有评论(0)