ExMobi+Agile Lite开发内置浏览器APP
来自: http://my.oschina.net/nandy007/blog/608359
微信对内置浏览器的定制封装,使得H5的流量入口再次重新被定义。在原生程序中使用H5也成为非常必要的一种搭配。这也得益于H5对于简单的浏览性质的内容可以很好的进行展现和传播。
由于在实际项目中有需要在移动端使用到H5,而大部分H5页面都是来源于网络的,所以这里尝试使用ExMobi+Agile Lite来开发一个内置浏览器的功能。
相对于传统的浏览器功能,由于移动端具有丰富的本地能力可以调用,比如:二维码扫描、本地存储、各类第三方SDK分享等等,让移动端的浏览器可以更加个性化。
而我们一般看到的移动端浏览器功能通常包括:
1.输入地址跳转页面或者输入关键字搜索。
2.更够扫描二维码读取地址信息等进行展示。
3.能够前进、后退、刷新页面等基本导航操作。
4.可以收藏某些页面
5.可以将页面进行社会化分享。
更大一些的浏览器还可以做自己的门户,有自己的用户体系等等。
选择ExMobi + Agile Lite,主要是由于ExMobi有强大的UI展现能力可以支持原生UI和webview的多窗口混合展现,以及丰富的本地能力以及与第三方SDK集成的接口,可以方便调用摄像头、GPS、第三方SDK等能力,而Agile Lite作为开源、灵活的H5框架,对H5门户的UI和交互处理非常便捷,而且它内置了很多操作ExMobi本地能力的JS桥接类。
由于现在处于起步阶段,暂时功能做到1/2/3,首页的门户也比较简单,后续会把各个部分和多窗口支持起来。
目前代码很简单,只需要两个页面,若干图片和Agile Lite框架就可以。
先上效果图再上源码:
首页门户,目前只是一些热门的网站的链接,后续可以借助ExMobi服务端的集成能力抓爬和采集一些热门的资讯/新闻/天气等信息进行展现,还可以结合企业系统把企业的一些待办信息在此进行展示,形成一个以h5为入口的企业门户。
点击门户的淘宝icon就会跳转打开淘宝手机版页面。当然如果做为企业使用,也可以通过门户来打开独立的app程序而不仅仅是H5链接地址。
如果用户输入的是关键字,自动调用百度进行搜索,后续规划中会搭建一个内部搜索系统,可以对内部信息和系统进行查询,返回符合企业信息的数据,展示的内容相较于百度搜索会更加丰富,可以是图文/音频/链接/app等,甚至还有一些实时的推送消息。
目前的浏览器客户端还很简单,只有两个页面,一个是UIXML,一个是HTML页面,其中UIXML页面作为程序首页展现一个原生窗口和部分原生UI,中间放置一个webview组件指向HTML页面展示门户。
UIXML页面的代码如下:
<header> <div style="border-size:0; background-color: #ffffff;"> <input type="text" id="urlDom" style="width:80%;border-size: 0;" prompt="请输入网址或关键字"></input> <div style="width: 20%; text-align: right; padding:0 6 0 0;" id="goBtn" href="doGo()"> <img class="footer_menu" src="res:image/app/ic_menu_search_holo_light.png"></img> </div> <hr/> </div> </header> <body style="padding:0;margin:0;" onload="doLoad()"> <webview id="wvDom" url="" plusready="doReady()" backmonitor="true"></webview> </body> <footer style="padding:10 0;"> <div style="width: 25%; text-align: center;"> <img class="footer_menu" id="backBtn" href="doBack()" src="res:image/app/back.png"></img> </div> <div style="width: 25%; text-align: center;"> <img class="footer_menu" id="forwardBtn" href="doForward()" src="res:image/app/forward.png"></img> </div> <div style="width: 25%; text-align: center;"> <img class="footer_menu" id="refreshBtn" href="doRefresh()" src="res:image/app/ refresh.png"></img> </div> <div style="width: 25%; text-align: center;"> <img class="footer_menu" id="scalBtn" href="doScal()" src="res:image/app/qrcode.png"></img> </div> </footer>
这里充分利用的了ExMobi的UIXML原生组件进行布局,构建原生的窗口,在窗口顶部和底部放置原生的按钮组件以及支持h5的webview组件,通过JS来达到原生UI与h5的交互,实现前进、后退、刷新、扫描、搜索等功能,这个页面里执行了一些函数,如下:
var BMC = function(options){ this.opts = { wvDom : document.getElementById(options.wvDom), firstUrl : options.firstUrl }; }; BMC.prototype.utils = {}; BMC.prototype.utils.checkURL = function(URL){ var str= URL||''; var Expression = /^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/; var objExp = new RegExp(Expression); return objExp.test(str); }; BMC.prototype.utils.showToast = function(msg){ var toast = new Toast(); toast.setText(msg); toast.setDuration(1000); toast.show(); }; BMC.prototype.getOpts = function(){ return this.opts; }; BMC.prototype.init = function(){ var opts = this.opts; opts.wvDom.loadUrl(opts.firstUrl); }; BMC.prototype.go = function(url){ if(!url){ alert('请输入网址'); return; } if(this.utils.checkURL(url)){ this.opts.wvDom.loadUrl(url); }else if(this.utils.checkURL('http://'+url)){ this.opts.wvDom.loadUrl('http://'+url); }else{ this.opts.wvDom.loadUrl('http://m.baidu.com/s?word='+EncryptionUtil.urlEncode(url, 1)); } }; BMC.prototype.refresh = function(){ this.opts.wvDom.refresh(); }; BMC.prototype.back = function(){ if(!this.opts.wvDom.canBack()){ this.utils.showToast('已经是第一页了'); return; } this.opts.wvDom.back(); }; BMC.prototype.forward = function(){ if(!this.opts.wvDom.canForward()){ this.utils.showToast('已经是最后一页了'); return; } this.opts.wvDom.forward(); }; function doLoad(){ var url = 'res:page/www/index.html'; var bmc = new BMC({ wvDom : 'wvDom', firstUrl : url }); window.doReady = function(){ var opts = bmc.getOpts(); var url = opts.wvDom.getUrl(); var urlDom = document.getElementById('urlDom'); urlDom.value = url.indexOf('file')==0?'':url; opts.wvDom.executeScript('document.addEventListener("backmonitor",function(){ nativePage.executeScript("doCheckBack()"); history.go(-1);}, false);'); } window.doGo = function(){ var url = document.getElementById('urlDom').value; bmc.go(url); }; window.doBack = function(){ bmc.back(); }; window.doForward = function(){ bmc.forward(); }; window.doRefresh = function(){ bmc.refresh(); }; window.decode = new Decode(); window.doScal = function(){ decode.onCallback = decodeCallback;/*设置解码结束回调函数*/ decode.startDecode();/*开始解码*/ }; window.decodeCallback = function(){ if(!decode.isSuccess()){/*返回解码是否成功*/ bmc.utils.showToast('二维码错误'); }else{ bmc.go(decode.result); } }; window.doCheckBack = function(){ var opts = bmc.getOpts(); if(!opts.wvDom.canBack()) close(); } bmc.init(); }
可以看出,代码中主要操作的就是ExMobi的webview组件,以达到对h5页面的控制。、
再来看看HTMML页面代码:
<!-- HTML5文件 --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0"> <title>首页</title> <link rel="stylesheet" href="assets/agile/css/agile.layout.css"> <link rel="stylesheet" href="assets/agile/css/flat/flat.component.css"> <link rel="stylesheet" href="assets/agile/css/flat/flat.color.css"> <link rel="stylesheet" href="assets/agile/css/flat/iconline.css"> <link rel="stylesheet" href="assets/agile/css/flat/iconlogo.css"> </head> <body > <div id="section_container"> <section id="icon_logo_section" data-role="section" class="active"> <article data-role="article" id="main_article" data-scroll="verticle" class="active" style="top:0px;bottom:0px;"> <div class="scroller padded text-center"> <div class="grid" data-col="3"> <div class="grid-cell" data-href="http://www.qq.com"> <div class="grid-img bg-alizarin"><span class="iconfont iconlogo-logo-qq"></span></div> <label class="grid-label">腾讯</label> </div> <div class="grid-cell" data-href="http://www.taobao.com"> <div class="grid-img bg-carrot"><span class="iconfont iconlogo-logo-taobao"></span></div> <label class="grid-label">淘宝</label> </div> <div class="grid-cell" data-href="http://m.baidu.com"> <div class="grid-img bg-peter-river"><span class="iconfont iconlogo-logo-baidu"></span></div> <label class="grid-label">百度</label> </div> <div class="grid-cell" data-href="http://m.weibo.cn"> <div class="grid-img bg-wet-asphalt"><span class="iconfont iconlogo-logo-sinaweibo"></span></div> <label class="grid-label">微博</label> </div> <div class="grid-cell" data-href="http://weixin.qq.com/"> <div class="grid-img bg-nephritis"><span class="iconfont iconlogo-logo-wechat"></span></div> <label class="grid-label">微信</label> </div> <div class="grid-cell" data-href="http://www.fhss.com.cn/"> <div class="grid-img bg-orange"><span class="iconfont iconlogo-logo-starrysky"></span></div> <label class="grid-label">烽火</label> </div> <div class="clearfix"></div> </div> </div> </article> </section> </div> <!--- third ---> <script src="assets/third/jquery/jquery-2.1.3.min.js"></script> <script src="assets/third/jquery/jquery.mobile.custom.min.js"></script> <script src="assets/third/iscroll/iscroll-probe.js"></script> <script src="assets/third/arttemplate/template-native.js"></script> <!-- agile --> <script type="text/javascript" src="assets/agile/js/agile.js"></script> <!-- app --> <script type="text/javascript" src="assets/app/js/app.js"></script> <script> $('[data-href]').on(A.options.clickEvent, function(){ location.href = $(this).data('href'); return false; }) </script> </body> </html>
由于功能比较简单,主要是引用了Agile Lite框架的基本JS和CSS进行布局。
我们可以看到,在UIXML中的布局既有UIXML原生组件,也可以由webview组件展示H5,可以让原生UI和H5界面展现更好的融合在一起,相互搭配。
而UIXML中也调用了ExMobi提供的二维码扫描JS API,后面要做的本地收藏、社会化分享等ExMobi都有很好的支持。特别是ExMobi特有的支持的多窗口模式,一个应用中可以打开多个UIXML文件,也就是一个一个独立的窗口,并且都具有原生窗口的生命周期事件继承,可以让页面之间的交互更加灵活。
后续的新功能再更新咯。