HTML5技术

浅谈Hybrid技术的设计与实现第二弹 - 叶小钗(2)

字号+ 作者:H5之家 来源:H5之家 2016-06-03 12:00 我要评论( )

window.requestNative requestNative(JSON.stringify(params)); 3 return ; ifr = $('iframe src="' + url + '"/' ); 6 $('body' ).append(ifr); 7 setTimeout( function () { 8 ifr.remove(); 9 ifr = null ; 10 }

window.requestNative && requestNative(JSON.stringify(params)); 3 return; ifr = $('<iframe src="' + url + '"/>'); 6 $('body').append(ifr); 7 setTimeout(function () { 8 ifr.remove(); 9 ifr = null; 10 }, 1000)

优劣

URL Schema与JavaScriptCore的优劣不好说,还是看具体使用场景吧,不考虑参数问题的话,真正有使用经验的朋友可能会发现url schema方案可能更加适用,因为:

URL Schema方案是监控Webview请求,所以比较通用;而JavaScriptCore的注入是在Webview加载时候注入。
如果页面刷新,这个注入也就丢了需要做特殊处理(糯米接入一个常见BUG就是糯米容器提供的方法不执行)

使用JavaScriptCore的话,页面刷新会导致Hybrid项目瘫痪的问题,我们IOS同事首先调整了注入方法的时间点,放到了webViewDidFinishLoad中,因为webViewDidFinishLoad的注入在页面js声明之后,所以如果一来就有Hybrid的交互便不会执行,比如:

Hybrid.ui.header.set({ 3 title: '设置右边按钮', 4 });

所以我与Native约定在webViewDidFinishLoad后执行一个我定义的方法,我们将页面初始化逻辑放到这个事件里面,比如:

1 Hybrid.ready = function() { 2 hybridInit(); 3 }

对比这个方法与之前jQuery的dom ready有点类似,我们可能会担心这样会影响页面的渲染速度,这里特别做了一个测试,这段代码对真实逻辑执行确实有一定影响,首次启动在30-90ms之间,第二次没什么影响了,这里也形成了一个一个优化点,只将那种页面一加载结束就需要执行的逻辑放入其中,影响主页面的逻辑可优先执行,如果觉得麻烦便直接将页面的载入放到这个方法中即可。

选择建议

根据我们的使用过程,发现JavaScriptCore还是不好用,因为对Native的不熟悉,在js方法注入的时间点一块我们踩了一些坑,我们想在webViewDidFinishLoad中注入方法,但是发现有一定几率是页面js已经执行完了才注入,导致Hybrid交互失效。

而且我们对Native一块声明js方法的生命周期与垃圾回收一块也不熟悉,总担心埋下什么坑,加之之前30-90ms的延迟,我们最终是实现了两套方案:

一般情况下仍旧使用URL Schema,如果有不满足的场景,我们会使用JavaScriptCore,因为底层架构搭建不能耗费太多时间,所以对JavaScriptCore的研究便暂时到此,后续有时间需要对他做深入研究。

Hybrid版本

APP会有版本号概念,每个版本会加一些新的特性或者会改一些BUG,一般的版本号是1.0.0,如果改了BUG打了补丁是1.0.1,有新特性就是1.1.0,如果有大改变的话就2.0.0咯,我们在实际业务代码中可能会有用到版本号的地方,所以Native需要将当前版本号告诉我们,一般是采用Native篡改navigator.userAgent写入特殊标志实现,我们这里是写入了这种标识:

xxx hybrid_1.0.0 xxx

然后我们会在全局释放一个工具类方法获取当前版本号:

1 var getHybridInfo = function () { 2 var platform_version = {}; 3 var na = navigator.userAgent; 4 na = na.toLowerCase(); 5 var info = na.match(/hybrid_\d\.\d\.\d/); 6 if (info && info[0]) { 7 info = info[0].split('_'); 8 if (info && info.length == 2) { 9 platform_version.platform = info[0]; 10 platform_version.version = info[1]; 11 } 12 } 13 return platform_version; 14 };

于是,我们在业务开发中便能知道当前是不是处于Native容器中,和获取版本号。

根据之前的共识,我们的代码只要运行在Native容器中就应该表现的像Hybrid,在浏览器中就应该表现的像H5

上面这句话可能很多朋友觉得有点奇怪,这里的界限在于有些方法H5提供了Native也提供了,究竟该用哪个的问题,比如获取当前位置信息,如果在Native容器中自然走Native获取,如果在浏览器中那就走H5接口。

交互格式约定

做一件事情重中之重的就是基础约定,我们这里做Hybrid架构首先就要做好交互格式约定,这种格式约定的要灵活一点,这个将会在后续扩展中提现他的优势,我们这里依旧采用类似Ajax的交互规则:

请求格式

1 requestHybrid({ tagname: 'hybridapi', param: {}, callback: function (data) { 8 } 9 });

tagname是标志这次请求的唯一标识,在接口比较多的情况有可能会有命名空间,比如:tagname: 'ns/api'。

回调格式

回调的方式都是Native调用H5的js方法,前端需要告诉Native去哪个对象拿回调方法,另外前端需要与Native约定返回时所带的参数,我们是这样设计的:

{ data: {}, errno: 0, msg: "success" }

其中每个错误码需要详细的约定,比如:

{ data: {}, errno: 1, msg: "APP版本过低,请升级APP版本" }

但是真实业务调用的时候却不需要特别去处理响应数据,因为前端应该有统一的地方处理,到具体业务回调时应该只需要使用data数据即可。

调用方式的困惑

一般来说,H5与Native通信都只会使用一个方法,我们之前是H5创建url schema,后面有有了新的方案,是Native释放一个requestNative给H5调用,这里就产生了一个之前没有的问题:

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • .NET插件技术-应用程序热升级 - 把爱延续

    .NET插件技术-应用程序热升级 - 把爱延续

    2017-04-20 12:01

  • 前端开发框架简介:angular和react - 腾讯云技术社区

    前端开发框架简介:angular和react - 腾讯云技术社区

    2017-04-11 18:02

  • 浓缩的才是精华:浅析GIF格式图片的存储和压缩 - 腾讯云技术社区

    浓缩的才是精华:浅析GIF格式图片的存储和压缩 - 腾讯云技术社区

    2017-04-07 15:08

  • 面向个人的技术咨询服务 - 思想瞭望者

    面向个人的技术咨询服务 - 思想瞭望者

    2017-04-05 12:07

网友点评
o