uniapp开发APP之强制更新和热更新的实现
前言
app和h5相比,有着更新延迟和更新难的特性,h5在部署更新后可以保证所有用户访问的都是最新的功能,而app则可能存在多个版本,用户也可以选择不升级继续使用;
但是有时候,app进行了大规模的调整,导致之前所有版本的app都不可用,或者一些重要功能作出了调整(比如收费内容发生改变),强制用户需要更新app,这样的情况并不少见;
因此在第一版本的app内,就应该把包内更新的功能加上,以保证app的更新续航。
整包更新和热更新
APP的更新分为整包更新和热更新。
整包更新是指下载完整apk文件进行覆盖安装。
热更新是指把app有改动的地方打包进wgt文件,只更新wgt文件中的内容,不进行整包安装,在用户视角也叫做省流量更新
版本号约束
既然是版本更新,那就离开版本号的约束。
因为涉及两种更新方式,所以要先制定版本号的规范:
建议 严格遵循 Semantic Versioning 2.0.0 语义化版本规范。
主版本号:不兼容的 API 修改
次版本号:向下兼容的功能性新增
修订号:向下兼容的问题修正
实现原理
- 开发后台版本管理功能,每次发版上传android安装包,记录版本号、是热更新还是整包更新、是否强制更新等
- 每次打开app(onLaunch生命周期)的时候,通过接口请求最新版本信息,再获取当前安装包信息,对比版本号
- 如果版本号不一致,且接口获取的版本号大于当前应用的版本号,则进行整包更新或热更新。
- 需要注意的是,ios并不存在下载安装包覆盖安装这种操作,所以在ios平台需要跳转到appstore进行更新
export default { onLaunch: function() { // 条件编译,只在app环境下进行更新操作 // #ifdef APP-PLUS if (process.env.NODE_ENV === 'production') { // 只在正式环境下启用,避免更新影响开发和测试环境(这步取决于你的需求) // 获取app运行信息 plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) { // 通过接口获取最新版本信息,具体请求不演示 getVersion({ platform: '1' }).then(res => { if (!res) { return; } // 版本号得到的是类似 '7.0.1'的字符串,把它去除.并转为纯数字 const appCode = parseInt(res.app_code.split('.').join('')) const version = parseInt(widgetInfo.version.split('.').join('')) if (appCode > version) { // 只有接口版本号 > 当前包版本号才进行更新 // type为0热更新(看接口设计) if (res.type == '0') { // 热更新,下载更新文件,这一步可以先显示更新提示的ui,用户点击更新后再下载更新 this.updateHot(res.download_url) } else if (res.type == '1') { // 整包更新,这一步可以先显示更新提示的ui,用户点击更新后再下载更新 this.updatePackage(res.download_url) } } }).catch(err => { console.error(err) }) }); } }, methods: { // 整包更新 updatePackage(url) { // ios平台不允许这样更新,所以我们需要跳转到appstore进行更新 if (uni.getSystemInfoSync().platform === 'ios') { plus.runtime.launchApplication({ action: 'itms-apps://xxx' // 链接可以通过接口获取 }); } else { this.isDownloading = true // 构建了下载任务,但此时并未开始下载 const dtask = plus.downloader.createDownload(url, {}, (downloadResult, status) => { if (status === 200) { plus.runtime.install(downloadResult.filename, { force: false }, function() { plus.runtime.restart(); // 安装成功后重启 }, function(e) { uni.showToast({ icon: 'none', title: '下载更新失败' }) }); } } ); // 执行安装包下载 dtask.start(); } }, // 热更新 updateHot(url) { uni.downloadFile({ url, success: (downloadResult) => { if (downloadResult.statusCode === 200) { // 下载更新文件成功后进行安装 plus.runtime.install(downloadResult.tempFilePath, { force: false // 是否强制安装, 如果将要安装应用的版本号不高于现有应用的版本号则终止安装,并返回安装失败。 }, function() { uni.showToast({ title:'更新完毕,即将重启', icon: 'none', position: 'bottom' }) setTimeout(() => { plus.runtime.restart(); // 安装完成后重启应用 },2000) }) } } }); } } }
其他方案
插件市场提供了uni-upgrade-center升级方案,包含了后台管理app版本以及app自动更新的逻辑,需要注意的是后台管理是基于uni-admin框架的插件,如果应用内没有使用uni-admin,集成起来会相对麻烦
参考资料
总结
到此这篇关于uniapp开发APP之强制更新和热更新的文章就介绍到这了,更多相关uniappAPP强制更新和热更新内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
js获取当前年月日时分秒的方法实例(new Date()/moment.js)
JavaScript是一种流行的编程语言,它可以用来获取当前年月日,这篇文章主要给大家介绍了关于js获取当前年月日时分秒的相关资料,分别使用的是new Date()/moment.js,需要的朋友可以参考下2024-07-07使用JavaScript脚本无法直接改变Asp.net中Checkbox控件的Enable属性的解决方法
今天工作中遇到个小问题,情况如下,当我在后台页面中设置Checkbox的Enable的值为false时,我在前端页面中使用脚本(chk.disabled = false),无法改变disabled的值为false,下面看看小编是怎么解决此问题的,需要的朋友一起了解了解吧2015-09-09JavaScript对象拷贝与Object.assign用法实例分析
这篇文章主要介绍了JavaScript对象拷贝与Object.assign用法,结合实例形式分析了javascript深拷贝与浅拷贝以及Object.assign的功能与相关使用技巧,需要的朋友可以参考下2018-06-06
最新评论