关于H5App更新(Dcloud)
2017-11-14 本文已影响0人
ZIFeng_
对于H5App的升级官方也给了比较详细的文档,这里我只是做个人的学习笔记
H5App升级有三种方式
1.整包升级:适用于大版本更新,runtime发生变化时(模块、配置、版本等变化)必须使用此更新方法
2.资源升级:适用于小版本更新 。runtime不变,前端页面整体压缩包更新
3.应用资源差量升级:适用于小版本更新 。runtime不变,前端页面仅需要更新的部分更新(暂时未使用)。
首先看整包升级,这个逻辑其实非常简单,主要又三个步骤:
1.检查是否有新版本
这个操作其实非常简单,就是客户端与升级服务器的一次交互操作,比较升级服务器上发布的最新客户端版本是否高于当前客户端版本号(5+ API中可以通过
plus.runtime.version
获取当前apk/ipa的版本号,注意打包方生效)?是的话则需要升级,否则无需升级。
从逻辑上来考虑有两种判断模式:
1.1. 客户端判断是否有升级
客户端从服务器获取最新的版本号,本地js判断是否需要升级。
1.2. 服务器判断是否有升级
客户端提交版本到服务器,有服务器判断返回是否需要升级。
前者的优点是否服务器压力小,静态返回最新客户端版本即可,后者的优点则升级控制会更灵活,可以根据其它条件动态控制部分用户先升级(灰度发布)等。有条件的情况推荐采用第二种方式进行判断。
可以使用Javascript中的标准XHR请求,如果存在跨域问题则使用5+ API的
XMLHttpRequest
2.下载新版本
如果判断到需要更新版本,则需要从服务器下载新版本,通常升级服务器应该返回下载新版本的地址(或者从固定的地址获取)。
调用Downloader
API下载,示例如下:
var downloadUrl=""; // 下载文件地址
var dtask = plus.downloader.createDownload( downloadUrl, {}, function ( d, status ) {
if ( status == 200 ) { // 下载成功
var path = d.filename;
console.log(d.filename);
} else {//下载失败
alert( "Download failed: " + status );
}
});
dtask.start();
3.安装新版本
下载原生安装包apk后,可调用plus.runtime.install
方法安装,示例如下:
plus.runtime.install(path); // 安装下载的apk文件
注意
iOS平台的ipa无法安装,此时需要跳转到appstore,提示用户自动点击升级更新,跳转到appstore的方法为打开应用的appstore地址,示例如下:
var url='itms-apps://itunes.apple.com/cn/app/hello-h5+/id682211190?l=zh&mt=8';// HelloH5应用在appstore的地址
plus.runtime.openURL(url);
此处url是以"itms-apps://"开头,后面跟appstore上应用地址。
再看应用资源升级
1.生成资源升级包
-
在HBuilder中编辑好新的移动App资源后,更新manifest.json的版本号
原来版本是1.0.0,新版本修改为1.0.1: 修改版本号
-
在HBuilder中生成升级包文件(wgt)
选中项目,右键“发行” -> “制作移动App资源升级包”: 生成资源升级包
2.应用检测更新资源
检测服务器上是否有新版本
- 获取当前应用的版本号
var wgtVer = null;
function plusReady() {
// 获取本地应用资源版本号
plus.runtime.getProperty(plus.runtime.appid, function(inf) {
wgtVer = inf.version;
console.log("当前应用版本:" + wgtVer);
checkUpdate();
});
}
if(window.plus) {
plusReady();
} else {
document.addEventListener('plusready', plusReady, false);
}
- 发起ajax请求检测是否有新版本
var checkUrl = "http://192.168.1.108:8087/vue_service/api/update/CheckVersion";
// 检测更新
function checkUpdate() {
plus.nativeUI.showWaiting("检测更新...");
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
switch(xhr.readyState) {
case 4:
console.log(xhr.status);
//getVer();
plus.nativeUI.closeWaiting();
if(xhr.status == 200) {
var newVer = JSON.parse(xhr.responseText).newVersion;
console.log("检测更新成功:" + newVer);
if(wgtVer && newVer && (wgtVer != newVer)) {
plus.nativeUI.alert("发现新版本!");
downWgt(); // 下载升级包
} else {
plus.nativeUI.alert("无新版本可更新!");
}
} else {
console.log("检测更新失败!");
plus.nativeUI.alert("检测更新失败!");
}
break;
default:
break;
}
}
xhr.open('GET', checkUrl);
xhr.send();
}
更新应用资源
- 从服务器下载应用资源包(wgt文件)
var wgtUrl = "http://192.168.1.108:8087/vue_service/update/H51739A6E.wgt";
// 下载wgt文件
function downWgt() {
plus.nativeUI.showWaiting("下载wgt文件...");
plus.downloader.createDownload(wgtUrl, {
filename: "_doc/update/"
}, function(d, status) {
if(status == 200) {
console.log("下载wgt成功:" + d.filename);
installWgt(d.filename); // 安装wgt包
} else {
console.log("下载wgt失败!");
plus.nativeUI.alert("下载wgt失败!");
}
plus.nativeUI.closeWaiting();
}).start();
}
- 更新应用资源包(wgt文件)
// 更新应用资源
function installWgt(path) {
plus.nativeUI.showWaiting("安装wgt文件...");
plus.runtime.install(path, {}, function() {
plus.nativeUI.closeWaiting();
console.log("安装wgt文件成功!");
plus.nativeUI.alert("应用资源更新完成!", function() {
plus.runtime.restart();
});
}, function(e) {
plus.nativeUI.closeWaiting();
console.log("安装wgt文件失败[" + e.code + "]:" + e.message);
plus.nativeUI.alert("安装wgt文件失败[" + e.code + "]:" + e.message);
});
}
- 检测更新更好的模式应该是客户端提交本地应用资源版本号到升级服务器,由升级服务器判断是否可更新并且返回App升级资源包下载地址,避免在客户端写资源下载地址;
- 更新时可以在后台静默下载,下次启动是直接更新,避免更新时打断用户操作。