uniapp实现app热更新的方法
清慕 人气:0啊~时隔多月终于闲下来了。最近整理了下资料发现热更新在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 为更新包的请求接口方法 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包,然后点击生成就可以了,然后就等待打包,更新包一般比安装包快且没有次数限制
还有值得注意的是记得每次打包记得更改版本号跟版本名称这两个地方哦
加载全部内容