[uni-app] wgt热更新方案处理记录

文章目录

      • 资源
      • 方案
      • 注意点
      • 代码

资源

HTML5-下载/安装wgt

方案

流程介绍:
1.APP启动 - 调用wgt包检测, 判断是否需要进行热更
1.1 需要更新: 执行下载->安装->更新wgt包版本号->提示并重启
1.2 不需要更新: 无操作
(以上均是静默操作, 不影响APP启动流程)

方案说明:
1.OSS存放wgt包
2.Dcloud账号的云数据库存放wgt/version等配置数据
3.uniApp本地检测wgt包版本号进行比对, 判断后决定是否下载/安装/跳过/更新wgt包本地版本号等

数据库简单结构

{
    "version": "1.0.8",// uniApp版本号
    "config": {
        "ios": {
            "app_wx_login": true
        },
        "android": {
            "app_wx_login": true
        },
        "mini": {
            "app_wx_login": false
        },
        "wgt": {
            "tag": 1, //wgt包版本号
            "config": {}
        }
    }
}

可以看到, 我们在云数据库中配置好 wgt字段的 tag, APP 通过查数据库中各自对应的app(如1.0.8)版本,来读取wgt对应的tag版本号, 在进行wgt下的 : 远端tag 与 本地tag 比对( 这里tag的版本号直接使用自然序号即可, 足够用)
通过tag的比对, 进行逻辑处理即可,

注意点

1.安装包提示 WGT安装包中manifest.json文件的version版本不匹配问题
由于wgt包版本号的维护不依赖于uniapp 版本号, 所以 可以在安装wgt包的时候, 强制忽略版本判断
[uni-app] wgt热更新方案处理记录_第1张图片
2.OSS存放wgt包
通过oss存放wgt包

xxxxx/wgt/1/index.wgt
可以看到, 通过读取远端的wgt的tag, 用该tag进行oss地址的拼接, 用于作为下载地址

代码

1.数据库的查询与结果返回, 此处我用vuex来处理. (顺便进行数据库对app的数据缓存)

/**
	 * 检测wgt包
	 * appInfo: appInfo,
	 * wgtLocalTag : 本地wgt包的tag, 如果首次安装或未进行过热更新, tag为null
	 * 调用:APP初始化时, 调用进行检测
	 * 
	 */
	checkWgt({ commit }, appInfo) {
		let WGT_TAG_FLAG = "wgtTagFlag";
		let wgtV = uni.getStorageSync(WGT_TAG_FLAG);
		return new Promise((reslove) => {
			let db = uniCloud.database();
			db.collection("xxxxxconfig")
				.where(`version == "${appInfo.appVersion}"`)
				.get()
				.then(
					res => {
						if (res.success) {
							let dataArr = res?.result?.data;
							let data = dataArr[0]; // 按设计, 每个版本的配置, 只有一个版本号对应一条数据配置
							if (!data) {
								console.log('--- 热更新检测: 数据库查询为空 - 不处理')
								reslove({})
								return;
							}
							commit("certAppConfig", data)
							console.log(data?.version)
							console.log(data?.config)
							console.log(data?.config?.wgt?.tag)
							let remoteV = data?.config?.wgt?.tag
							// 远端未配置热更新
							if (!remoteV) {
								console.log('--- 热更新检测: 远端无热更新版本 - 不处理')
								reslove({})
								return
							} else {
								// 首次热更新
								if (!wgtV) {
									console.log('--- 热更新检测: 首次触发热更新 - 更新')
									// 返回 下载url / storage字符串
									reslove({
										wgtUrl: 'https://cdn.xxxx.com/static/wgt/' +
											remoteV + "/index.wgt",
										saveKey: WGT_TAG_FLAG,
										wgtTag: remoteV
									})
									return;
								}
								// 远端版本高于本地版本
								if (wgtV < remoteV) {
									console.log('--- 热更新检测: 有热更新版本 - 更新')
									// 返回 下载url / storage字符串
									reslove({
										wgtUrl: 'https://cdn.xxxx.com/static/wgt/' +
											remoteV + "/index.wgt",
										saveKey: WGT_TAG_FLAG,
										wgtTag: remoteV
									})
									return;
								}
								// 远端版本小于等于本地版本 - 不处理
								if (wgtV >= remoteV) {
									console.log('--- 热更新检测: 远端版本小于等于本地版本 - 不处理')
									reslove({})
									return
								}
							}
						}
					})
				.catch(err => {
					reslove({})
				})
		})
	}
  1. 版本检测
/**
 * wgt包检测
 * 检测资源来自于云数据库
 * 返回值, 是否需要进行提示 or 静默下载
 */
const wgtCheck = () => {
	// #ifdef APP-PLUS
	store.dispatch('db/checkWgt', getSystemInfo()).then(async res => {
		if (res.wgtUrl) {
			try {
				// 下载wgt包 (下载设定:超时90s/ 重试2次/ 重试间隔10s)
				let filename = await wgtDown(res.wgtUrl);
				// 下载成功 - 安装wgt包
				if (!filename) {
					return
				}
				let install = await wgtInstall(filename);
				// 更新本地wgt包版本号
				console.log('--- 热更新检测: 安装成功,更新wgtTag版本号')
				uni.setStorageSync(res.saveKey, res.wgtTag)
				// 重启APP
				plus.nativeUI.alert("最新资源(v:" + (res.wgtTag) + ")加载成功,即将重启", () => {
					plus.runtime.restart();
				})
			} catch (e) {
				// 失败- 静默处理
			}
		}
	})
	// #endif
}
  1. 下载
/**
 * wgt 包下载 
 * 下载失败 提示 or  静默
 */
const wgtDown = (wgtUrl) => {
	// #ifdef APP-PLUS
	return new Promise((resolve, reject) => {
		// 下载wgt文件
		// plus.nativeUI.showWaiting("最新文件下载中..."); // 提示文字屏蔽
		plus.downloader.createDownload(wgtUrl, {
			filename: "_doc/update/",
			timeout: 90, // 默认120秒,
			retry: 2, // 设置重试次数, 默认3次
			retryInterval: 10, // 设置重试间隔5s, 默认30s
		}, function(d,
			status) {
			if (status == 200) {
				console.log('--- 热更新检测: 下载wgt成功 - yes')
				console.log(":" + d.filename);
				resolve(d.filename)
			} else {
				console.log('--- 热更新检测: 下载wgt失败 - no')
				// plus.nativeUI.alert("最新内容下载失败..."); // 提示文字屏蔽
				reject()
			}
			// plus.nativeUI.closeWaiting(); 
		}).start();
	})
	// #endif
}
  1. 安装
/**
 * wgt包 安装(含副作用)
 * 安装成功 or 静默不提示
 */
const wgtInstall = (path) => {
	// #ifdef APP-PLUS
	return new Promise((resolve, reject) => {
		// 更新应用资源
		if (!path) {
			reject()
			return
		}
		plus.nativeUI.showWaiting("应用资源文件安装中...");
		// 忽略mainfirst中的版本号, 用checkWgt函数已经处理
		plus.runtime.install(path, { force: true }, function() {
			plus.nativeUI.closeWaiting();
			console.log('--- 热更新检测: 安装wgt文件成功! - yes')
			resolve();
		}, function(e) {
			plus.nativeUI.closeWaiting();
			console.log("--- 热更新检测: 安装wgt文件失败[" + e.code + "]:" + e.message);
			plus.nativeUI.alert("安装wgt文件失败[" + e.code + "]:" + e.message);
			reject()
		});
	})
	// #endif
}

实际操作注意点
要进行热更新
1.oss中必须先放置好wgt包, 以防数据库配置好了, 却找不到资源
2.配置数据库, 各大版本的uniapp的version中, 选你要进行热更的版本, 配置wgt (这就是本方案的取缺点, 需要手动配置, 不过在条件不完善的情况下, 先这样吧)

你可能感兴趣的:(uni-app)