使用uniapp开发实现 app热更新

啊~时隔多月终于闲下来了。最近整理了下资料发现热更新在app开发是经常见的,基本必备而且确实很方便,所以就总结了点东西给大家看看,有问题可以一起讨论

一、实现热更新需要那些东西

需要服务器存放更新包资源,后端提供接口用于检测当前版本是否为最新版本。(增删改查)
热更新的流程其实很简单,如下图所示

用户进入应用
检测是否有更新
需要更新
请求资源更新包
下载安装
下载完成重启
取消下载
不需要更新
正常运行

二、具体流程代码

1.获取当前应用app版本

// 保存 app 版本信息
// #ifdef APP-PLUS
plus.runtime.getProperty(plus.runtime.appid, (widgetInfo)=> {
	// console.log('widgetInfo', widgetInfo);
	this.version = widgetInfo.version;
});
// #endif

2.获取服务器上更新包的资源(包含下载链接,更新包版本),比较当前版本是否为最新版本,不是则弹出提示更新最新版本

checkWgtFun() {
	//loginApi.getPatchManage() 获取更新包接口
	loginApi.getPatchManage().then(res=> {
		console.log('检查更新包', res);
		if(res.code == 200) {
			let result = res.data.versionNum // 更新包版本
			if(this.version.substr(0, 3) * 1 >= result.substr(0, 3) * 1){
				this.$toast('当前为最新版本');
				return
			} 
			if(this.version.replace(/\./g, "") * 1 >= result.replace(/\./g, "") * 1){
				this.$toast('当前为最新版本');
				return
			}
			uni.showModal({
				title: '提示',
				content: '发现有新版本可以升级',
				cancelText: '取消更新',
				confirmText: '立即更新',
				success: res1 => {
					if (res1.confirm) {
						console.log('用户点击确定');
						// 补丁下载安装
						// this.versionNum=res.data.versionNum
						this.downWgt(res.data.patchUrl)
					} else if (res1.cancel) {
						console.log('用户点击取消');
					}
				},
				fail: (err) => {
					console.log('下载失败', err);
				}
			});
		} else {
			this.$toast(res.msg);
		}
	})
	},

3.用户选择更新版本下载更新包

// 下载补丁
// patchUrl 更新包下载路径
downWgt(patchUrl) {
	let _this=this
	this.downloadTask = uni.downloadFile({
		url:patchUrl,
		success: (downloadResult) => {
			if (downloadResult.statusCode === 200) {  
				// 安装应用
				plus.runtime.install(
					downloadResult.tempFilePath, 
					{force: false}, 
				()=> {  
					plus.nativeUI.toast('最新版本下载完成')
					// 安装成功之后关闭应用重启app
					plus.runtime.restart();  
				}, (e)=> {  
					plus.nativeUI.toast("补丁安装失败")// 常见问题:版本号,appId
				});  
			}
		},
		fail: (err) => {
			plus.nativeUI.toast("补丁下载失败")
		}
	})
},
// 用户取消更新,中断下载
cancel() {
	if(this.downloadTask) {
		this.$toast('取消下载安装!')
		this.downloadTask.abort()
		this.downloadTask = null
	}
},

到此就完成了热更新的功能,看着不难吧,最后贴出我写的完整的代码,最好封装成一个组件

<template>
	<view>
		<view @click="checkApp" v-if="verShow">
			<u-cell-item title="检查新版本" :value='version' :arrow='false'></u-cell-item>
		</view>
		<u-mask :show="show">
				<view class="warp">
					<view class="version">
						<view class="new-version">发现新版本</view>
						<view style="color: #fff;">v {{versionNum}}</view>
						<view class="be-updating">正在更新</view>
						<u-line-progress :percent='schedule.progress' :show-percent='false' active-color='#4B86FE' striped striped-active></u-line-progress>
						<view class="down-prog">{{schedule.totalBytesWritten}}/{{schedule.totalBytesExpectedToWrite}}</view>
						<view class="cancel" @click="cancel">取消升级</view>
					</view>
				</view>
			</u-mask>
	</view>
</template>

<script>
	import {mineApi,loginApi} from '@/api/myAjax.js'
	import filters from '@/common/filters.js'
	export default {
		props:{
			verShow:{
				type:Boolean,
				default:true
			},
			
		},
		data() {
			return {
				versionNum:'',
				schedule:{},
				show: false,
				downloadTask:null,
				time:10,
				isCheck:false
				// versionText:''
			};
		},
		computed:{
			version() {
			 	// 获取版本号(在其他地方需要用到所以存了全局变量)
				return getApp().globalData.version
			}
		},
		methods:{
			// 检查补丁更新
			checkWgtFun() {
				loginApi.getPatchManage().then(res=> {
					console.log('检查补丁更新包', res);
					console.log('<this.globalData.version>', uni.getStorageSync('appVersion'));
					if(res.code == 200) {
						let result = res.data.versionNum
						if(this.version.substr(0, 3) * 1 > result.substr(0, 3) * 1){
							if(this.verShow){
								this.$toast('当前为最新版本');
							}
							return
						} 
						if(this.version.replace(/\./g, "") * 1 >= result.replace(/\./g, "") * 1){
							if(this.verShow){
								this.$toast('当前为最新版本');
							}
							return
						}
						uni.showModal({
							title: '提示',
							content: '发现有新版本可以升级',
							cancelText: '取消更新',
							confirmText: '立即更新',
							success: res1 => {
								if (res1.confirm) {
									console.log('用户点击确定');
									console.log(res);
									// 补丁下载安装
									this.versionNum=res.data.versionNum
									this.downWgt(res.data.patchUrl)
								} else if (res1.cancel) {
									console.log('用户点击取消');
								}
							},
							fail: (err) => {
								console.log('下载失败', err);
							}
						});
					} else {
						this.isCheck = false
					}
				})
			},
			// 下载补丁
			downWgt(patchUrl) {
				let _this=this
				console.log(patchUrl);
				this.isCheck = false
				this.show = true
				this.downloadTask = uni.downloadFile({
					url:patchUrl,
					success: (downloadResult) => {
						if (downloadResult.statusCode === 200) {  
							// 安装应用
							plus.runtime.install(downloadResult.tempFilePath, {force: false}, ()=> {  
								_this.show =false
								plus.nativeUI.toast('最新版本下载完成')
								// 安装成功之后重启
								plus.runtime.restart();  
							}, (e)=> {  
								_this.show =false
								plus.nativeUI.toast("补丁下载失败")
							});  
						}
					},
					fail: (err) => {
						_this.show =false
						plus.nativeUI.toast("补丁下载失败")
					}
				})
				this.downloadTask.onProgressUpdate((res) => {
					// 当前下载进度
					if(this.time%10==0){
						this.schedule=res
						this.schedule.totalBytesExpectedToWrite=filters.sizeMB(res.totalBytesExpectedToWrite)
						this.schedule.totalBytesWritten=filters.sizeMB(res.totalBytesWritten)
					}
					this.time+=1
				});
			},
			// 关闭蒙层 中断下载
			cancel() {
				if(this.downloadTask) {
					this.$toast('取消下载安装!')
					this.downloadTask.abort()
					this.downloadTask = null
					this.show=false
					this.schedule={}
				}
			},
		}
	}
</script>

<style lang="scss" scoped>
.version{
	width: 521rpx;
	height: 583rpx;
	font-size: 24rpx;
	padding: 207rpx 44rpx 33rpx;
	background: url(/static/mine/gxt.png) no-repeat;
	background-size: 100% 100%;
	.new-version{
		font-size: 30rpx;
		color: #fff;
		margin-bottom: 7rpx;
		height: 45rpx;
		line-height: 45rpx;
	}
	.be-updating{
		margin-top: 96rpx;
		margin-bottom: 14rpx;
	}
	.down-prog{
		margin: 14rpx 0;
	}
	.cancel{
		text-align: right;
		color: #2CA6F8;
	}
}
</style>

filters.js文件


function sizeMB(size){
	if(size<1024){
		return size+'B'; 
	}else if(size/1024>=1 && size/1024/1024<1){
		return Math.floor(size/1024*100)/100+'KB';
	}else if(size/1024/1024>=1){
		return Math.floor(size/1024/1024*100)/100+'MB';
	}
}
export default {
	sizeMB
}

最后在附上如何打包更新包,这个也简单,跟打包安装包一样
在这里插入图片描述

选择制作wgt包,然后点击生成就可以了,然后就等待打包,更新包一般比安装包快且没有次数限制
在这里插入图片描述

还有值得注意的是记得每次打包记得更改版本号跟版本名称这两个地方哦
在这里插入图片描述
有缘下次见!!!!

  • 12
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
uniapp app开发热更新可以通过以下步骤实现: 1. 在uni-app项目的根目录下创建一个名为`update`的文件夹,用于存放热更新的资源文件。 2. 在`update`文件夹中创建一个名为`manifest.json`的文件,用于记录热更新的版本信息和资源文件列表。示例内容如下: ```json { "version": "1.0.0", "packages": [ { "path": "update.zip", "md5": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx" } ] } ``` 其中,`version`表示当前热更新的版本号,`packages`数组中的每个对象表示一个资源包,`path`表示资源包的路径,`md5`表示资源包的MD5值。 3. 将需要热更新的资源文件打包成一个zip文件,命名为`update.zip`,并放置在`update`文件夹中。 4. 在uni-app项目的`main.js`文件中添加热更新的代码。示例代码如下: ```javascript import { checkUpdate, downloadUpdate, applyUpdate } from 'uni-updater'; // 检查是否有新版本 checkUpdate({ url: 'http://example.com/update/manifest.json', // 热更新资源的manifest.json文件的URL success: (res) => { if (res.hasUpdate) { // 下载新版本资源 downloadUpdate({ url: 'http://example.com/update/update.zip', // 热更新资源的zip文件的URL success: (res) => { // 应用新版本资源 applyUpdate({ success: () => { // 热更新成功 }, fail: (err) => { // 热更新失败 } }); }, fail: (err) => { // 下载资源失败 } }); } }, fail: (err) => { // 检查更新失败 } }); ``` 以上代码中,`checkUpdate`函数用于检查是否有新版本的热更新资源,`downloadUpdate`函数用于下载新版本的热更新资源,`applyUpdate`函数用于应用新版本的热更新资源。 请注意,以上代码中的URL需要替换为实际的热更新资源的URL。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值