版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wwq444968579/article/details/53323028
1、在html页面中使用window和document对象调用ExMobi的能力问题。
有的开发者在uixml中调用了window.getParameter()获取一个参数,在html里也想这么写就不行了,因为html里的window对象是标准浏览器的window对象;
同样的,在uixml中使用document.cache.setCache()是可以,在html中的document则没有cache对象。
这里需要先扯一件事情,uixml里的js也支持window和document对象,但是uixml其实跟html完全不一样的,uixml是原生UI的xml描述文件,所以uixml的window对象和document对象并不等于html里的window对象和document对象。
html页面是必须依赖uixml页面存在的,而且uixml与位于其中的html是可以互相交互的;而不同的uixml之间是可以进行数据交互的,所以要想位于不同uixml中的html也能实现交互是可行的。
所以,要使用这种方法需要了解:
1、uixml和uixml之间如何交互?
uixml页面是可以设置id的,可以在其他uixml中通过id来获取一个uixml的窗口对象,并通过callFunction函数来调用uixml里的某个函数,比如:
复制代码
2、uixml和html之间如何交互?
uixml和html之间可以通过executeScript函数来调用,但是区别在于:html中的executeScript函数属于nativePage内置对象,而uixml中的executeScript函数则属于webview控件对象。
比如在main.html中要调用uixml中函数为:
复制代码
而在index.uixml中调用index.html中的函数为:
复制代码
只要掌握这两个问题的处理就可以轻松的在uixml里的html之间进行交互
方法二:使用ExMobi的生命周期实现
我们知道,uixml中的html可以监听到ExMobi的生命周期事件(还不了解的童鞋可以猛戳http://bbs.exmobi.cn/thread-3395-1-1.html)
所以如果利用ExMobi的生命周期事件我们也可以做一些简单的逻辑处理。
由于是在html中直接监听生命周期事件,参数无法传递,所以这里就需要借助到本地缓存也就是CacheUtil工具类。
比如,在index.html中使用Agile Lite的html控制器打开form.html页面,这时候就可以不用开发者自己创建uixml(Agile Lite会自动创建,但是对开发者是透明的)
在form.html关闭前可以将参数存到缓存中,如下:
复制代码
那form.html关闭后就会回到index.html,这时候就会触发index.html的onstart事件,监听此事件并获取缓存就可以做一些逻辑操作,比如:
复制代码
解决方案:
其实很简单,ExMobi的window类在html里对象的类不是window,而是ExMobiWindow,所以,前面提到的uixml中的window.getParameter()在html就可以这么写
ExMobiWindow.getParameter()。
但是uixml的document对象则没有这么封装,因为uixml里的document和html里的document差别太大,并不互通,没有必要封装到html里,但是cache确是比较特殊的经常会使用,所以,上面的document.cache类在html封装成了CacheUtil,所以,uixml中的document.cache.setCache在html中的写法就是CacheUtil.setCache
ExMobiWindow.getParameter()。
但是uixml的document对象则没有这么封装,因为uixml里的document和html里的document差别太大,并不互通,没有必要封装到html里,但是cache确是比较特殊的经常会使用,所以,上面的document.cache类在html封装成了CacheUtil,所以,uixml中的document.cache.setCache在html中的写法就是CacheUtil.setCache
2、在html中调用window.close为啥关不掉页面?
这个问题跟上一个问题可以归为一类,但是又有所不同。
这里又要扯一件事情,ExMobi中是以uixml窗口为单位的页面,所以html页面的展示实际也必须要有一个uixml窗口来承载的(uixml页面中使用webview才能支持html展示,html页面不可独立存在)。
所以当我们想要关闭一个html页面的时候,在html页面中使用window.close,这个方法在标准浏览器上的行为是关闭当前浏览器的窗口,所以我们会发现没有任何效果,经过前面扯淡,大家可以清楚,我们要关闭的应该是uixml的窗口,在html中如何关闭它所在的uixml窗口呢,所以我们要在uixml的窗口对象中关闭,也就是问题1中的ExMobiWindow.close()就可以关闭了。
这个问题跟上一个问题可以归为一类,但是又有所不同。
这里又要扯一件事情,ExMobi中是以uixml窗口为单位的页面,所以html页面的展示实际也必须要有一个uixml窗口来承载的(uixml页面中使用webview才能支持html展示,html页面不可独立存在)。
所以当我们想要关闭一个html页面的时候,在html页面中使用window.close,这个方法在标准浏览器上的行为是关闭当前浏览器的窗口,所以我们会发现没有任何效果,经过前面扯淡,大家可以清楚,我们要关闭的应该是uixml的窗口,在html中如何关闭它所在的uixml窗口呢,所以我们要在uixml的窗口对象中关闭,也就是问题1中的ExMobiWindow.close()就可以关闭了。
如何让两个webview中的html互相传值操作:
在使用HTML5开源框架Agile Lite的时候,我们可能需要对两个html页面之间进行交互。
我们知道ExMobi中支持html是通过在uixml中使用webview来指向html页面地址来实现的,所以两个html页面之间是无法直接进行交互的。
这里我们介绍两种方法,第一种是使用uixml进行桥接实现;第二种则是使用ExMobi的生命周期实现。
目前主推的是第二种,但是希望童鞋们对第一种也要充分了解,因为第一种方法是利用ExMobi本质核心原理,所以理解了其他的方法就不难了。
我们知道ExMobi中支持html是通过在uixml中使用webview来指向html页面地址来实现的,所以两个html页面之间是无法直接进行交互的。
这里我们介绍两种方法,第一种是使用uixml进行桥接实现;第二种则是使用ExMobi的生命周期实现。
目前主推的是第二种,但是希望童鞋们对第一种也要充分了解,因为第一种方法是利用ExMobi本质核心原理,所以理解了其他的方法就不难了。
方法一:使用uixml进行桥接实现
此方法是充分使用ExMobi窗口之间的交互原理:
- function doSend(username, password){
- //通过index.uixml页面的id获取此页面的窗口对象
- var indexWin = PageUtil.getWindowById('index');
- //调用window的callFunction对象调用index.uixml里的函数
- indexWin.callFunction('doGet("'+username+'","'+password+'")');
- //最后关闭自身
- window.close();
- }
- $('#submit').on(A.options.clickEvent, function(){
- var username = $('#username').val();
- var password = $('#password').val();
- //nativePage是ExMobi在html中内置的对象,用于操作uixml里的函数
- //这时候需要main.uixml中有一个doSend的函数
- nativePage.executeScript('doSend("'+username+'","'+password+'")');
- });
- function doGet(username, password){
- //通过webview的id获取webview对象
- var webview = document.getElementById('browser');
- //webview对象通过executeScript函数来调用html里的函数
- //这时候要求index.html中要有一个doRefresh函数
- webview.executeScript('doRefresh("'+username+'","'+password+'")');
- }
- $('#submit').on(A.options.clickEvent, function(){
- var username = $('#username').val();
- var password = $('#password').val();
- //将要传的参数存到cache中
- CacheUtil.setCache('username', username);
- CacheUtil.setCache('password', password);
- ExMobiWindow.close();
- });
- //监听onstart生命周期事件
- $(document).on('onstart', function(){
- //从cache中获取参数
- var username = CacheUtil.getCache('username');
- var password = CacheUtil.getCache('password');
- $('#ratchet_article #username').text(username);
- $('#ratchet_article #password').text(password);
- //如果有必要的话需要清除缓存
- CacheUtil.remove('username');
- CacheUtil.remove('password');
-
- });
由于一直以来第三方程序调用ExMobi客户端传参格式不一致,Android传参需要进行base64编码,而iOS不需要编码,导致第三方调用存在误解,故从ExMobi5.10.0客户端版本开始统一Android和iOS程序调用ExMobi的参数要求,第三方Android程序调用ExMobi客户端传参的时候,参数不需要进行base64编码。
如果之前已经有用到此功能而现在需要升级到5.10.0及以上版本,可以有两种方式应对:
方式一:
由第三方程序修改传参,传递的参数不进行base64编码。uixml中不需要改动,通过window.getNativeParameter(key)得到的就跟原来的版本一致
方式二:
第三方程序传参不变,仍然为base64编码。uixml中根据DeviceUtil.getOs()判断系统类别为android,则使用window.getNativeParameter(key)得到base64编码的参数,并调用EncryptionUtil.base64Decode(src)对得到的参数进行base64解码得到最终的参数