目录
HTML5+APP应用升级这边主要推荐两种方式,一种是整包升级,即更新发新版客户端,客户通过更新下载新版客户端安装更新,另一种是应用资源包升级,通过压缩资源包下载更新升级到全新的版本。还有一种是差量应用资源升级,不太推荐,对于移动应用APP最稳固的升级方法就是制定升级周期,定期进行整包升级,这样会对于投入生产环境的应用系统影响最小,虽然这种方式也有一定的缺点,但是能够保证系统稳定性。下面将对这三种方式分别进行说明。
整包升级
适用于较大版本更新,runtime发生变化时(模块、配置、版本等变化)必须使用此更新方法,其升级步骤也比较简单,如下:
- 查询是否有新版本更新
- 下载新版本
- 安装新版本
查询是否有新版本更新
这个操作其实非常简单,就是客户端与升级服务器的一次交互操作,比较客户端服务器上发布的最新客户端版本是否高于当前客户端版本号(5+ API中可以通过plus.runtime.version获取当前apk/ipa的版本号)。
从逻辑上来考虑有两种判断模式:
- 客户端判断是否有升级
客户端从服务器获取最新的版本号,本地js判断是否需要升级。 - 服务器判断是否有升级
客户端提交版本到服务器,有服务器判断返回是否需要升级。
前者的优点是否服务器压力小,静态返回最新客户端版本即可,后者的优点则升级控制会更灵活,可以根据其它条件动态控制部分用户先升级(灰度发布)等。有条件的情况推荐采用第二种方式进行判断。
可以使用Javascript中的标准XHR请求,如果存在跨域问题则使用5+ API的XMLHttpRequest。
下载新版本
如果判断到需要更新版本,则需要从服务器下载新版本,通常版本升级服务器应该返回下载新版本的地址(或者从固定的地址获取)。有两种下载方法,一种调用Downloader API下载,示例如下:
复制代码var url=""; // 下载文件地址
var dtask = plus.downloader.createDownload( url, {}, function ( d, status ) {
if ( status == 200 ) { // 下载成功
var path = d.filename;
console.log(d.filename);
} else {//下载失败
alert( "Download failed: " + status );
}
});
dtask.start();
安装新版本
下载原生安装包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上应用地址。
示例
在Hbuiler中,Hello H5+和Hello mui示例里,有2种不同的检查更新处理方式。
Hello H5+里的update.js比较复杂,在js里执行下载apk并安装的逻辑。
Hello mui里的update.js比较简单,弹出新包下载地址到浏览器,由浏览器执行下载逻辑。
如何选择看自己的要求。
应用资源包升级
5+应用资源独立升级,相对整包升级有以下优势:
- 无需重新提交应用市场审核更新,降低更新周期;
- 无需用户手动点击操作安装更新,优化用户体验;
- App资源相对整包体积更小,升级速度更快。
生成移动App资源升级包
-
在HBuilder中编辑好新的移动App资源后,更新manifest.json的版本号
原来版本是1.0,新版本修改为2.0: -
在HBuilder中生成升级包文件(wgt)
菜单“发行” -> “制作移动App资源升级包”:
在以下界面中通过“浏览”按钮选择保存路径,点击“确定”保存wgt文件: -
生成wgt后提交到手机可访问的网络地址
App资源升级包下载地址:
http://www.dcloud.io/docs/a/update/H5EF3C469.wgt
为了模拟正常的升级检测流程,添加以下检测升级地址(返回最新版本号):
http://demo.dcloud.net.cn/test/update/check.php
在应用中检测更新资源
检测版本服务器上是否有新版本
-
获取当前应用的版本号
复制代码
var wgtVer=null; function plusReady(){ // ...... // 获取本地应用资源版本号 plus.runtime.getProperty(plus.runtime.appid,function(inf){ wgtVer=inf.version; console.log("当前应用版本:"+wgtVer); }); } if(window.plus){ plusReady(); }else{ document.addEventListener('plusready',plusReady,false); }
-
发起ajax请求检测是否有新版本
复制代码
// 检测更新 var checkUrl="http://demo.dcloud.net.cn/test/update/check.php"; function checkUpdate(){ plus.nativeUI.showWaiting("检测更新..."); var xhr=new XMLHttpRequest(); xhr.onreadystatechange=function(){ switch(xhr.readyState){ case 4: plus.nativeUI.closeWaiting(); if(xhr.status==200){ console.log("检测更新成功:"+xhr.responseText); var newVer=xhr.responseText; if(wgtVer&&newVer&&(wgtVer!=newVer)){ downWgt(); // 下载升级包 }else{ plus.nativeUI.alert("无新版本可更新!"); } }else{ console.log("检测更新失败!"); plus.nativeUI.alert("检测更新失败!"); } break; default: break; } } xhr.open('GET',checkUrl); xhr.send(); }
更新应用资源
-
从版本资源服务器下载应用资源包(wgt文件)
复制代码
// 下载wgt文件 var wgtUrl="http://demo.dcloud.net.cn/test/update/H5EF3C469.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); }); }
wgt更新原生层是通过文件夹重命名方式实现,要么全部更新成功,要么更新失败,不会出现仅部分文件更新的情况
App store应用更新说明
应用资源更新肯定是违反apple政策的,但目前看起来,如果你不是很大的公司,apple不会理睬你。如果你是大公司,建议不要做整体更新,每次更新几个页面,也不要提示更新后需要重启,这样会安全点。
差量应用资源升级
5+应用资源差量升级,相对App资源独立升级,因为只需要下载更新的资源文件,所以升级包体积更小,升级速度会更快。
注意:需HBuilder5.7.0以上版本才有此功能
生成移动App资源差量升级包
顾名思义,差量升级包是针对某个历史版本到新版本的差量,所以对于升级服务器来讲需要保留所有历史版本,并且分别生成每个历史版本到新版本的差量升级包。
目前HBuilder IDE并未提供版本控制系统,所以需要按照以下规则手动生成差量升级包:
- 差量升级包文件格式为wgtu
在HTML5+移动App支持的差量升级包文件后缀名必须是wgtu,它是标准的zip压缩文件,可以使用任何zip工具对wgtu目录进行压缩,并修改文件后缀名称为wgtu。 - wgtu目录结构
名称 | 类型 | 说明 |
---|---|---|
www | 目录 | 保存需要更新的数据文件,其下的目录结构与应用的目录结构一致,其下必须包含manifest.json文件,否则认为更新文件非法,不执行升级操作 |
update.xml | 文件 | 保存应用升级操作的配置信息,参考update.xml文件格式 |
- update.xml文件格式(注意:文件名必须全部小写)
update.xml为标准的xml文件格式,定义wgtu文件升级配置信息,其文件格式如下:
元素名称 | 父元素 | 类型 | 描述 | 必须 |
---|---|---|---|---|
wgtu | 根节点 | |||
appid | wgtu | 属性 | 升级应用的appid | 是 |
basis | wgtu | 节点 | 基础应用信息 | 是 |
version | basis | 属性 | 基础应用的版本信息(旧版本的版本号) | 是 |
remove | wgtu | 节点 | 升级需要删除的文件/目录列表 | 否 |
item | remove | 节点 | 需要删除的项 | 否 |
path | item | 属性 | 需要删除的项的路径,相对于应用根目录,如“image/a.png”表示image目录下的a.png文件。如果是目录则以‘/’结尾,如“res/img/”表示res目录下的img目录,删除时包括下的所有内容。 | 否 |
- wgtu示例
应用升级前的版本1.0,其应用目录结构为:
应用升级后的版本1.1,其应用目录结构为:
差量升级包wgtu文件的目录结构为(不包括最外层wgtu目录):
应用升级更新文件manifest.json、index.html,新增detail.html、image/new.png,删除image/icon5.png。
其中update.xml中的内容为:复制代码
<?xml version="1.0" encoding="utf-8" standalone="no"?> <wgtu appid="TEST" > <basis version="1.0" /> <remove> <item path="image/icon5.png" /> </remove> </wgtu>
应用中差量更新资源
下载wgtu文件并更新:
复制代码 var url='http://demo.dcloud.net.cn/helloh5/update/HelloH5.wgtu';
plus.nativeUI.showWaiting("升级中...");
var dtask = plus.downloader.createDownload( url, {method:"GET"}, function(d,status){
if ( status == 200 ) {
console.log( "Download wgtu success: " + d.filename );
plus.runtime.install(d.filename,{},function(){
plus.nativeUI.closeWaiting();
plus.nativeUI.alert("Update wgtu success, restart now!",function(){
plus.runtime.restart();
});
},function(e){
plus.nativeUI.closeWaiting();
alert("Update wgtu failed: "+e.message);
});
} else {
plus.nativeUI.closeWaiting();
alert( "Download wgtu failed: " + status );
}
} );
dtask.addEventListener('statechanged',function(d,status){
console.log("statechanged: "+d.state);
});
dtask.start();
注意
- wgtu包中的update.xml文件名称必须全部小写,并且和www在同一级目录中
- wgtu包中www目录下必须包含manifest.json文件,并且里面不能包含注释(HBuilder中默认带注释,需要手动删除所有注释)
- update.xml中的appid值是应用的AppID(如“H5F6AE111”),不是程序的包名(如“io.dcloud.H5F6AE1111”)
- wgtu包必须是使用zip格式压缩的文件(不能使用如rar等其它压缩格式)