uniapp项目App热更新详解

1,757 阅读2分钟

功能介绍

概念: 整包更新是指用户需要重新下载并安装整个应用的新版本,而资源热更新则是指应用在不重新安装的情况下,仅更新应用内部的某些资源或代码。

注意: 修改了配置文件需要重新打包 , 热更新无效

uniapp-App热更新

修改更新项 : 这个每次打包都要更改

image.png

打包wgt包 : 打包后需要给后端 , 用来更新

image.png

功能图解

image.png

代码实现

1、 所需变量介绍

// app版本更新Data
versionUpdate: {
    version: '1.0.0', //当前版本
    newVersion: '1.0.0',//更新版本
    versionContent: "",//更新内容
    downloadTask: null,//更新任务
    show: false,//更新弹框
    patchUrl: "",//更新wgt包
    schedule: { // 更新进度对象
        // 进度
        progress: "",
        // 已经下载长度
        totalBytesWritten: "",
        // 预期下载长度
        totalBytesExpectedToWrite: ""
    },
    time: 10 //更新进度更新间隔时间ms
}

更新的弹框可以自定义 , 也可以使用uni.model ,但是我觉得这个经常看的 ,还是单独写一个好看的比较好

如以下作者写的

image.png

2、检测版本

// 检测新版本
detectNewVersion(){
    plus.runtime.getProperty(plus.runtime.appid, (widgetInfo) => {
        // 拿到当前app版本
        let version = widgetInfo.version;
        this.versionUpdate.version = version;
        // 获取最新版本api接口 需要返回 version , content , source_download三个属性
        getPatchManage().then(res => {
            if (res.code == 200) {
                let data = res.data // 拿到数据
                this.versionUpdate.newVersion = data.version // 保存新版本--用来弹框展示
                this.versionUpdate.versionContent = data.content // 保存更新内容--用来弹框展示
                // 有新版本--进行更新
                if (data.version != version) {
                    this.versionUpdate.patchUrl = res.data.source_download // 保存新版本wgt包
                    this.versionUpdate.show = true // 显示更新弹框
                } else {
                    console.log("已是最新版本");
                }
            }
        });
    }) 
}

注意: 我这边比较时只是粗略的比较了是否相同 , 不相同就不是最新版本的 , 这个如果项目有需要可以修改成相应的比较

3、更新版本

// 新版本更新
versionUpdatePopupOpen() {
    let patchUrl = this.versionUpdate.patchUrl // 更新wgt包
    // 创建下载任务
    this.versionUpdate.downloadTask = uni.downloadFile({
        url: patchUrl,
        success: (downloadResult) => {
            if (downloadResult.statusCode === 200) {
                // 安装应用
                plus.runtime.install(    
                    downloadResult.tempFilePath, {
                        force: false
                    }, () => {
                        plus.nativeUI.toast('下载完成,正在重启app')
                        this.versionUpdate.show = false // 下载完成隐藏弹框
                        // 安装成功之后关闭应用重启app
                        plus.runtime.restart();
                    }, (e) => {
                        this.versionUpdate.show = false
                        plus.nativeUI.toast("补丁安装失败") // 常见问题:版本号,appId
                    }
                );
            } else {
                this.versionUpdate.show = false
                plus.nativeUI.toast("补丁下载异常") // 常见问题:版本号,appId
            }
        },
        fail: (err) => {
            this.versionUpdate.show = false
            plus.nativeUI.toast("补丁下载失败")
        }
    })
    // 监听下载进度--展示下载进度
    this.versionUpdate.downloadTask.onProgressUpdate((res) => {
        // 每10ms更新下载进度展示
        if (this.versionUpdate.time % 10 == 0) {
            this.versionUpdate.schedule = res
            this.versionUpdate.schedule.totalBytesExpectedToWrite = tui.sizeMB(res.totalBytesExpectedToWrite)
            this.versionUpdate.schedule.totalBytesWritten = tui.sizeMB(res.totalBytesWritten)
        }
        this.versionUpdate.time += 1
    });
}

4、取消更新


// 取消更新
versionUpdatePopupClose() {
    this.versionUpdate.show = false // 取消弹框
    // 如果正在更新--取消
    if (this.versionUpdate.downloadTask) {
        this.versionUpdate.downloadTask.abort()
        this.versionUpdate.downloadTask = null
        this.versionUpdate.schedule = {}
    }
},

写在最后

本次算是笔记分享吧 , 怕下次写这功能时要翻找资料 ,所以就一次性记录一下!