概要
cordova-hot-code-push-plugin(以下简称chcp)自身曾经反对主动查看更新、下载、装置,具体内容能够搜寻“cordova热更新”,或查看官网wiki。本文次要介绍如何应用chcp提供的JS API管制整个热更新过程,包含其中一些注意事项。本文仅针对安卓,iOS暂未验证。
需要背景
- 显示更新内容(弹窗)
- 可手动查看更新(点击按钮)
存在的问题
chcp提供的API根本能满足大部分性能,但为了满足需要还须要解决以下问题:
- 官网没有提供显示更新内容的办法
- 查看更新时,如果有更新,会等到下载实现才执行回调函数,导致操作长时间没有反馈;另一方面,如果有error(正在更新等),回调函数又会立刻执行
思路
针对问题1:在配置文件chcp.json中新增字段示意更新内容,并通过间接申请或调用API获取,比方"message":"1. bug修复..."
,并在具体流程中展现弹窗(本文是在更新内容下载实现后,也能够在查看到有更新的时候)
针对问题2:独自申请服务端的chcp.json,并跟本地的版本比拟,不同就认为有更新,能够立刻反馈给用户
API验证
getVersionInfo((err, data) => {...}) 获取版本信息
data.currentWebVersion
对应www/chcp.json中的release,本地配置,就是比拟版本要用到的data.readyToInstallWebVersion
本次要装置的版本,为空可能是没有获取到服务端配置,或者已是最新版data.previousWebVersion
更新后的上一个版本,为空阐明还没有更新过data.appVersion
版本号,对应config.xml中的widget的version,本地配置data.buildVersion
构建版本号,本地配置
理论测试,只有服务端的release
字段和本地的currentWebVersion
不同,chcp就认为须要更新,而不会查看appVersion
或者buildVersion
是否雷同(chcp.json中也没有这两个字段)。
fetchUpdate((err, data) => {...}, options) 获取更新
如果有更新,fetchUpdate
只有在下载实现所有更新后才执行回调函数。如果正在下载更新,回调函数会立刻执行,err.code
为-17。为了辨别上述两种状况且只有一次提醒,首次查看到有更新时,提醒能够应用setTimeout
延时,回调函数执行时,先clearTimeout
,再执行有error时的提醒。
须要留神的是,下载胜利后,回调函数中data的内容如下:
{ config: '"release":"xxx",...'}
其实就是把chcp.json的内容作为字符串作为config属性的值。如果要获取外面的值,须要做一次JSON解析。
isUpdateAvailableForInstallation((err, data) => {...}) 查看本地是否有可供装置的更新
如果没有调用过fetchUpdate
,或者曾经是最新版,则error存在,示意没有能够装置的更新,须要获取更新,具体参见官网示例。
installUpdate((err) => {...}) 执行装置
整体流程
- 比拟本地和服务端版本,版本不同 -> 2
- 查看本地是否有可装置的更新,没有 -> 3,有 -> 4
- 从服务端下载更新,会有以下几种状况:
a. 没有更新(个别不会呈现,除非1到3之间,server版本回退了...)
b. 正在下载更新中(没下载实现的时候,点击“查看更新”)
c. 不能应用热更新,须要更新包(原生代码有批改的时候,热更新曾经不能向后兼容)
d. 其余谬误
e. 失常下载实现 -> 4 - 弹窗显示更新内容,用户点击“立刻体验”后,装置更新,装置成后会间接刷新,目测是跳转到index
另外,最好将主动下载和主动装置敞开,避免抵触:
config.xml<chcp> <auto-download enabled="false" /> <auto-install enabled="false" /></chcp>
具体代码
// 获取本地的currentWebVersion,并和服务端的release比拟function compareVersion(serverVersion) { return new Promise((resolve, reject) => { window.chcp.getVersionInfo((error, data) => { console.log('getVersionInfo', data); if (error) { reject(error) } else { resolve(data.currentWebVersion === serverVersion); } }); });}// 申请服务端chcp.jsonfunction checkUpdate() { const url = "https://yourserver/chcp.json"; fetch(url).then(res => res.json()).then(data => compareVersion(data.release)).then(isEqual => { if (isEqual) { toast('已是最新版'); } else { // 流程2,查看是否有可装置更新 checkAvalilable(); } }).catch((error) => { console.log('checkUpdate failed', error) });}// 查看是否有可装置的更新function checkAvalilable() { console.log('checkAvalilable'); window.chcp.isUpdateAvailableForInstallation((error, data) => { if (error) { console.log('isUpdateAvailableForInstallation error', error); checkHotUpdate(); return; } // 已有可装置版本 beforeInstallAlert(); });}// 获取更新function checkHotUpdate() { console.log('checkHotUpdate'); const waitingId = setTimeout(() => { toast('有新版,开始更新'); }, 200); window.chcp.fetchUpdate((error, data) => { if (error) { console.log('fetchUpdate error', error); clearTimeout(waitingId); if (error.code == 2) { toast('已是最新版'); } else if (error.code == -17) { toast('正在下载更新中...'); } else if (error.code == -2) { // 须要下载apk } else { toast(`出错了: ${error.code}`); } return; } // 服务器版本信息 console.log('fetchUpdate data', data); // JSON解析config const config = data && data.config && JSON.parse(data.config); console.log('fetchUpdate config', config); // 下载实现,message为自定义字段,示意更新内容 beforeInstallAlert(config && config.message); });}function beforeInstallAlert(message) { // 弹窗逻辑,点击“立刻体验”调用installUpdate()}function installUpdate() { console.log('installUpdate'); window.chcp.installUpdate((error) => { if (error) { console.log('installUpdate error', error); toast(`装置失败: ${error.code}`); return; } console.log('installUpdate done'); });}
其余
err.code参见Error codes