啊~时隔多月终于闲下来了。最近整理了下资料发现热更新在app开发是经常见的,基本必备而且确实很方便,所以就总结了点东西给大家看看,有问题可以一起讨论
一、实现热更新需要那些东西
需要服务器存放更新包资源,后端提供接口用于检测当前版本是否为最新版本。(增删改查) 热更新的流程其实很简单,如下图所示
graph LR
A(用户进入应用) --> C{检测是否有更新}
C --> D(需要更新)
D --> E(请求资源更新包)
E --> F(下载安装)
F --> I(下载完成重启)
F --> J(取消下载)
C -->H(不需要更新)
H-->G(正常运行)
I --> G
J --> G
二、具体流程代码
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.versionNumthis.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=thisthis.downloadTask = uni.downloadFile({url:patchUrl,success: (downloadResult) => {if (downloadResult.statusCode === 200) {// 安装应用plus.runtime.install(downloadResult.tempFilePath, {force: false}, ()=> {plus.nativeUI.toast('最新版本下载完成')// 安装成功之后关闭应用重启appplus.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.versionNumif(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.versionNumthis.downWgt(res.data.patchUrl)} else if (res1.cancel) {console.log('用户点击取消');}},fail: (err) => {console.log('下载失败', err);}});} else {this.isCheck = false}})},// 下载补丁downWgt(patchUrl) {let _this=thisconsole.log(patchUrl);this.isCheck = falsethis.show = truethis.downloadTask = uni.downloadFile({url:patchUrl,success: (downloadResult) => {if (downloadResult.statusCode === 200) {// 安装应用plus.runtime.install(downloadResult.tempFilePath, {force: false}, ()=> {_this.show =falseplus.nativeUI.toast('最新版本下载完成')// 安装成功之后重启plus.runtime.restart();}, (e)=> {_this.show =falseplus.nativeUI.toast("补丁下载失败")});}},fail: (err) => {_this.show =falseplus.nativeUI.toast("补丁下载失败")}})this.downloadTask.onProgressUpdate((res) => {// 当前下载进度if(this.time%10==0){this.schedule=resthis.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 = nullthis.show=falsethis.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包,然后点击生成就可以了,然后就等待打包,更新包一般比安装包快且没有次数限制 
还有值得注意的是记得每次打包记得更改版本号跟版本名称这两个地方哦
最后
最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。




有需要的小伙伴,可以点击下方卡片领取,无偿分享
本文介绍了uni-app的热更新实现过程,包括检测版本、获取更新资源、用户下载更新包等步骤,并提供了相关代码示例,建议将代码封装成组件。同时提到了打包更新包的方法及注意事项,如更改版本号和版本名称。
1440

被折叠的 条评论
为什么被折叠?



