参考文档:https://www.cnblogs.com/sunylat/p/9896938.html 、https://www.jianshu.com/p/322e2801b4b6 以及 https://blog.csdn.net/wskai1/article/details/59055534
项目背景
使用 cordova + vue + mintui 开发混合 app(安卓版),需要提供热更新和版本升级功能。此处热更新指的是更新 h5 代码部分,比如修改了登录的样式没必要让用户去重新下载 app;版本升级就是需要用户下载 app 覆盖安装,这一般发生在 cordova 下载了新的插件去调用手机硬件功能。
热更新配置步骤:
-
安装 cordova 热更新插件
cordova plugin add cordova-hot-code-push-plugin
-
安装 cordova 热更新工具
npm install -g cordova-hot-code-push-cli
注意:该步可能失败,一是网速较慢,二是我的 npm 版本较低,安装了最新的 nodejs 后安装成功。(我的环境:node v14.15.5,npm 6.14.11)
-
在服务器可访问路径下创建一个目录,比如:www。该目录存放的是 cordova 工程的 www 目录下的所有文件。注意要保证该目录以 http 方式正常访问,而且json 格式的文件,也必须同样能以 http 方式访问到。
-
生成热更新相关配置文件
cordova-hcp init
执行该命令后会在 cordova 项目根目录下生成 cordova-hcp.json 文件,内容如下:
{ "name": "mobilemanage", "autogenerated": true, "ios_identifier": "", "android_identifier": "", "update": "start", "content_url": "http://61.164.57.186:18890/dev/ftp/www" }
“autogenerated”: true 这个值执行命令后是没有的需要自己手动添加,如果不添加网页内容更新将会无效。content_url 字段的值是步骤 3 中目录的地址。
cordova-hcp build
执行该命令后会在 cordova 项目的 www 目录中发现两个文件:chcp.json 和 chcp.manifest。
chcp.json 文件的内容如下:{ "name": "mobilemanage", "autogenerated": true, "ios_identifier": "", "android_identifier": "", "update": "start", "content_url": "http://61.164.57.186:18890/dev/ftp/www", "release": "2021.02.24-11.05.08" }
可以发现,chcp.json 比 cordova-hcp.json 多了一行内容。release 字段用于热更新的版本比较。
-
config.xml 文件配置(该文件位于 cordova 项目根目录下)
在 widget 标签内加入如下代码,url 的值为 chcp.json 文件在服务器的地址。<chcp> <config-file url="http://61.164.57.186:18890/dev/ftp/www/chcp.json"/> </chcp>
-
测试热更新功能
1) cordova 打包 apk 并安装至手机
cordova build android
2)修改页面内容后执行
cordova-hcp build
,重新生成 chcp.json 和 chcp.manifest。将 cordova 项目的 www 文件夹下的所有内容复制到步骤 3 的目录下。3)重新启动 app ,可以看到页面被修改。注意:页面修改不一定及时,可多次重启 app 查看效果。
版本升级配置步骤:
在完成热更新配置的基础上,完成下面步骤即可实现版本升级。
-
在config.xml 文件中的 chcp 标签内添加如下配置:
<auto-download enabled="false" /> <auto-install enabled="false" /> <native-interface version="1" />
auto-download:是否自动下载热更新代码,默认是 true,这里改为false,因为我们想控制下载的流程
auto-install:是否自动安装热更新代码,默认是 true,这里改为false,理由同上
native-interface:当前 native side 的版本号即 app 外壳版本号 -
在 cordova-hcp.json 文件中添加如下配置:
"min_native_interface": 1, "android_identifier": "http://61.164.57.186:18890/dev/ftp/app-debug.apk"
min_native_interface:在用 cordova-hcp.json 文件生成 chcp.json 文件后,(chcp.json 文件中的)该字段被用来和步骤 1 中的 native-interface 比较。两个值相同 ,不提示升级,但是网页内容可以更新。如果 xml 文件中的值大于服务器上的值,不会提醒更新,但是网页内容可以更新。小于服务上的值,提示应用需要更新升级,那么热更新将无法正常进行。
android_identifier:我们的 apk 未进驻安卓应用市场,因此该值配置的是需要下载的安装包在可访问的服务器上的路径 -
添加手动更新的 js 代码
因为我用了 Vue,因此我的 js 代码写在 main.js 文件内,并且在监听设备加载完成的函数内。chcp.fetchUpdate((error, data) => { if (error) { if (error.code === -2) { var dialogMessage = '发现新版本,为避免影响使用请更新'; //调用升级提示框 点击确认会跳转对应商店升级 chcp.requestApplicationUpdate(dialogMessage, null, null); } } })
以上代码的功能是检查本地安装版本和服务器 apk 版本大小,-2 代表 chcp.error.APPLICATION_BUILD_VERSION_TOO_LOW 即本地版本太低,需要下载 apk。因为我们的后端不打算维护多套代码,因此这里使用强制更新即在升级提示框出现后没有取消按钮,用户只能点击立即更新。这需要去改热更新插件的源码,注释掉设置取消按钮那一段。文件是 chcp 的 view 目录下的 AppUpdateRequestDialog,注释部分如下图所示。
-
测试版本升级功能出现的问题
1、 测试机配置 native-interface 版本为 1 ,服务器上 chcp.json 中 min_native_interface 值为 2,弹框提示是否更新,点击确定后弹出系统下载框询问是否下载app-debug.apk 。这里用户如果选择了取消,版本升级也将失败,因此我们并未实现强制更新。
2、不同机型和系统下载完 apk 后表现不同。华为 9.0 的手机下载完成会自动跳转到安装页面询问是否安装;小米 10.0 的手机下载完后只在消息通知栏提示,需要手动点击才能跳转到安装页面。
3、安装最新的 apk 发现未生效,遗漏了一个重要字段的更新。config.xml 文件 widget 标签有一个属性 version,每次升级 native-interface 字段的同时也要升级 version 字段。