uniapp实现app检查更新与升级详解(uni-upgrade-center)

作者:桌面漫游时间:2026-10-31 08:35:55浏览:97

本文详解uniapp中如何使用uni-upgrade-center插件实现App版本检查与升级。涵盖前台检测、后台管理及源码解析,介绍静默更新、强制更新及应用商店跳转逻辑。同时提供wgt资源包制作、manifest.json查看及常见报错解决方案,帮助开发者快速集成版本更新功能。

App检查更新与升级

参考链接:

升级中心uni-upgrade-center - App

uni-admin

h5+ api

App资源在线升级更新

uni-app使用plus注意事项

关于在线升级(WGT)的几个疑问

什么是升级中心uni-upgrade-center

uni-upgrade-center是uniapp官方提供的用于App版本更新的插件,其后端服务基于unicloud构建。

由于该插件开源,开发者可通过修改源码将后端服务替换为Java等其他服务端,后续章节将对源码进行解析。

升级中心主要由两部分组成:

前台检测更新模块:uni-upgrade-center-app

后台管理系统:

  • uni-admin >= 1.9.3:uni-admin已内置升级中心,可直接使用。原云函数upgrade-center已废弃,现使用uni-upgrade-center云函数。
  • uni-upgrade-center Admin管理后台 (uni-admin 1.9.3+ 已内置,此插件不再维护)
    • 1.9.0 <= uni-admin < 1.9.2:请前往Gitee下载tag v0.5.1版本使用
    • uni-admin < 1.9.0:请前往Gitee下载tag v0.4.2版本使用

简而言之,若使用的是新版uni-admin,直接启用内置的升级中心即可。

怎么使用uni-upgrade-center

使用方法并不复杂,按照官方文档操作即可。

简单来说,你需要在App项目中安装uni-upgrade-center-app插件,同时新建一个uni-admin项目用于上传和管理App的更新包。App项目通过unicloud请求获取更新包。

官方文档

如果不想使用unicloud,希望替换为Java等其他后端服务,或者想深入了解App检查更新与升级的代码实现,阅读uni-upgrade-center源码是非常必要的。

uni-upgrade-center源码阅读

强烈推荐阅读uni-upgrade-center源码。

通过逐步阅读uni-upgrade-center源码,基本可以完全掌握编写App检查更新与升级代码的方法。

源码前端功能实现主要涉及三个文件,建议依次阅读:

  • utils/call-check-version.js
  • utils/call-check-version.js
  • pages/upgrade-popup.vue

utils/call-check-version.js

代码逻辑简单,通过h5+ api获取应用信息,并将这些信息传递给uniCloud云函数。

同理,如果不使用云函数,而是传给Java等其他后端服务,只需替换云函数部分的代码即可。

export default function () {
  // #ifdef APP-PLUS
  return new Promise((resolve, reject) => {
    // 根据当前应用的appid,获取appid对应的应用信息
    plus.runtime.getProperty(plus.runtime.appid, function (widgetInfo) {
      const data = {
        action: 'checkVersion',
        appid: plus.runtime.appid,
        appVersion: plus.runtime.version,
        wgtVersion: widgetInfo.version
      }
      console.log("data: ", data);
      // 如果传给java等后端服务,改下方代码
      uniCloud.callFunction({
        name: 'uni-upgrade-center',
        data,
        success: (e) => {
          console.log("e: ", e);
          resolve(e)
        },
        fail: (error) => {
          reject(error)
        }
      })
    })
  })
  // #endif
  // #ifndef APP-PLUS
  return new Promise((resolve, reject) => {
    reject({
      message: '请在App中使用'
    })
  })
  // #endif
}

plus.runtime.appid

当前应用的APPID

String类型,只读属性

注意:如果在HBuilder真机运行,获取的是固定值"HBuilder"。需要提交App云端打包后运行,才能获取真实的APPID值。

plus.runtime.getProperty

获取指定APPID对应的应用信息

参数:

  • appid: (String) 必选,应用的Appid
  • getPropertyCB: (GetPropertyCallBack) 必选,获得应用信息成功回调函数

示例:

// 获取应用信息
function getAppInfo() {
	plus.runtime.getProperty( plus.runtime.appid, function ( wgtinfo ) {
		//appid属性
		var wgtStr = "appid:"+wgtinfo.appid;
		//version属性
		wgtStr += "<br/>version:"+wgtinfo.version;
		//name属性
		wgtStr += "<br/>name:"+wgtinfo.name;
		//description属性
		wgtStr += "<br/>description:"+wgtinfo.description;
		//author属性
		wgtStr += "<br/>author:"+wgtinfo.author;
		//email属性
		wgtStr += "<br/>email:"+wgtinfo.email;
		//features 属性
		wgtStr += "<br/>features:"+wgtinfo.features;
		console.log( wgtStr );
	} );
}

utils/call-check-version.js

官方实现了两种方式:静默更新和提示更新。

import callCheckVersion from './call-check-version'

// 推荐在App.vue中使用
const PACKAGE_INFO_KEY = '__package_info__'

export default function() {
	// #ifdef APP-PLUS
	return new Promise((resolve, reject) => {
		callCheckVersion().then(async (e) => {
			if (!e.result) return;
			const {
				code,
				message,
				is_silently, // 是否静默更新
				url, // 安装包下载地址
				platform, // 安装包平台
				type // 安装包类型
			} = e.result;

			// 此处逻辑仅为实例,可自行编写
			if (code > 0) {
				// 腾讯云和阿里云下载链接不同,需要处理一下,阿里云会原样返回
				const {
					fileList
				} = await uniCloud.getTempFileURL({
					fileList: [url]
				});
				if (fileList[0].tempFileURL)
					e.result.url = fileList[0].tempFileURL;

				resolve(e)

				// 静默更新,只有wgt有
				if (is_silently) {
					uni.downloadFile({
						url: e.result.url,
						success: res => {
							if (res.statusCode == 200) {
								// 下载好直接安装,下次启动生效
								plus.runtime.install(res.tempFilePath, {
									force: false
								});
							}
						}
					});
					return;
				}

				/**
				 * 提示升级一
				 * 使用 uni.showModal
				 */
				// return updateUseModal(e.result)

				/**
				 * 提示升级二
				 * 官方适配的升级弹窗,可自行替换资源适配UI风格
				 */
				uni.setStorageSync(PACKAGE_INFO_KEY, e.result)
				uni.navigateTo({
					url: `/uni_modules/uni-upgrade-center-app/pages/upgrade-popup?local_storage_key=${PACKAGE_INFO_KEY}`,
					fail: (err) => {
						console.error('更新弹框跳转失败', err)
						uni.removeStorageSync(PACKAGE_INFO_KEY)
					}
				})
				
				return
			} else if (code < 0) {
				// TODO 云函数报错处理
				console.error(message)
				return reject(e)
			}
			return resolve(e)
		}).catch(err => {
			// TODO 云函数报错处理
			console.error(err.message)
			reject(err)
		})
	});
	// #endif
}

/**
 * 使用 uni.showModal 升级
 */
function updateUseModal(packageInfo) {
	const {
		title, // 标题
		contents, // 升级内容
		is_mandatory, // 是否强制更新
		url, // 安装包下载地址
		platform, // 安装包平台
		type // 安装包类型
	} = packageInfo;

	let isWGT = type === 'wgt'
	let isiOS = !isWGT ? platform.includes('iOS') : false;
	let confirmText = isiOS ? '立即跳转更新' : '立即下载更新'

	return uni.showModal({
		title,
		content: contents,
		showCancel: !is_mandatory,
		confirmText,
		success: res => {
			if (res.cancel) return;

			// 安装包下载
			if (isiOS) {
				plus.runtime.openURL(url);
				return;
			}

			uni.showToast({
				title: '后台下载中……',
				duration: 1000
			});

			// wgt 和 安卓下载更新
			downloadTask = uni.downloadFile({
				url,
				success: res => {
					if (res.statusCode !== 200) {
						console.error('下载安装包失败', err);
						return;
					}
					// 下载好直接安装,下次启动生效
					plus.runtime.install(res.tempFilePath, {
						force: false
					}, () => {
						if (is_mandatory) {
							//更新完重启app
							plus.runtime.restart();
							return;
						}
						uni.showModal({
							title: '安装成功是否重启?',
							success: res => {
								if (res.confirm) {
									//更新完重启app
									plus.runtime.restart();
								}
							}
						});
					}, err => {
						uni.showModal({
							title: '更新失败',
							content: err
								.message,
							showCancel: false
						});
					});
				}
			});
		}
	});
}

静默更新

可以看出静默更新分为三步:

  • 后端提供一个下载更新包的url
  • 前端uni.downloadFile该url地址
  • 下载好后前端调用plus.runtime.install安装更新包
// 静默更新,只有wgt有
			if (is_silently) {
				uni.downloadFile({
					url: e.result.url,
					success: res => {
						if (res.statusCode == 200) {
							// 下载好直接安装,下次启动生效
							plus.runtime.install(res.tempFilePath, {
								force: false
							});
						}
					}
				});
				return;
			}

强制更新

首先,我们需要知道的是,plus.runtime.install成功后就已经安装完更新包了,用户下次打开App就会是最新版的App。这里强制更新的意思是是否立刻重启App,强制用户立刻使用最新版App。

plus.runtime.install后有三种应用场景,官方处理得很好,涵盖了三种情况:

  • 不征求客户意见,直接重启App,强制用户立刻使用最新版
  • 征求客户意见,如果重启,用户使用最新版,如果不重启,等用户下次打开App显示最新版
  • 不重启,等用户下次打开App显示最新版
			    // 安装下载的安装包,下次启动生效
					plus.runtime.install(res.tempFilePath, {
						force: false
					}, () => {
            // is_mandatory是后端返回的控制是否强制更新的变量
            // 强制更新就是强制重启app,否则就是用户下次打开app才会更新
            // 强制更新体验不好,还是下次打开更新会好很多
						if (is_mandatory) {
							// 更新完重启app
							plus.runtime.restart();
							return;
						}
						uni.showModal({
							title: '安装成功是否重启?',
							success: res => {
								if (res.confirm) {
									// 更新完重启app
									plus.runtime.restart();
								}
							}
						});
					}, err => {
						uni.showModal({
							title: '更新失败',
							content: err
								.message,
							showCancel: false
						});
					});

跳转应用商店

  • 后端返回安装包平台和安装包类型
  • 判断安装包类型是否是wgt,如果不是,判断安装包平台是否包含iOS,调用第三方程序打开url安装iOS更新包,iOS是跳转更新,其他是下载更新
  • iOS需要上架、通过市场安装,所以需要第三方程序打开url

plus.runtime.openURL表示调用第三方程序打开url进行安装,即跳转应用商店功能

function updateUseModal(packageInfo) {
	const {
		title, // 标题
		contents, // 升级内容
		is_mandatory, // 是否强制更新
		url, // 安装包下载地址
		platform, // 安装包平台
		type // 安装包类型
	} = packageInfo;

	let isWGT = type === 'wgt'
	let isiOS = !isWGT ? platform.includes('iOS') : false;
	let confirmText = isiOS ? '立即跳转更新' : '立即下载更新'

	return uni.showModal({
		title,
		content: contents,
		showCancel: !is_mandatory,
		confirmText,
		success: res => {
			if (res.cancel) return;

			// 安装包下载
			if (isiOS) {
				plus.runtime.openURL(url);
				return;
			}
      ...
		}
	});
}

用户取消下载

https://uniapp.dcloud.net.cn/api/request/network-file.html#downloadfile

var downloadTask = uni.downloadFile({
	url: 'https://www.example.com/file/test', //仅为示例,并非真实接口地址。
	complete: ()=> {}
});
downloadTask.abort();

如何打包wgt资源包

一、更改项目manifest.json中的应用版本名称与应用版本号

App检查更新与升级

二、HBuilderX>发行>原生App-制作应用wgt包>确定

App检查更新与升级

App检查更新与升级

三、开发测试的时候,记得再改回原先的应用版本名称与应用版本号,不然版本跟线上的相同,安装更新包的时候就会出现WGT安装包中manifest.json文件的version版本不匹配,本地测试不了更新效果

如何查看wgt文件manifest.json

wgt包生成后会是.wgt后缀名,更改其后缀名为.zip,再解压,就可以查看manifest.json了

报错解决:WGT安装包中manifest.json文件的version版本不匹配

manifest.json中的版本大于等于了线上的版本,自行排查即可

通过uni-admin上传wgt资源包

App检查更新与升级

uni-admin报错解决:超级管理员已存在

是因为admin账户是旧的,跟appid对不上,删除旧的admin账户,重新创建

总结

到此这篇关于uniapp实现App检查更新与升级(uni-upgrade-center)的文章就介绍到这了,更多相关uniapp App检查更新与升级内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

作者最新文章