本人最近在研究hybrid的实现原理且读了一些源码 仅限前端js的 所以非前端或非hybrid模式的童鞋可以绕过~
首先简介下url scheme
手机APP都有一个沙盒,可以注册自己的URL Scheme。我们可以通过系统的OpenURL来打开该app,并可以传递一些参数。例如:
CtripWireless://打开携程App
weixin:// 打开微信
目前大部分hybrid设计都是沿用JSBridge的,在不同的平台通过不同的native层实现,在各自平台下完成编译。
什么是JSBridge?
顾名思义,JSBridge就是定义Native和JS的通信,Native只通过一个固定的桥对象调用JS,JS也只通过固定的桥对象调用Native,基本原理是:
H5->通过某种方式触发一个url->Native捕获到url,进行分析->原生做处理->Native调用H5的JSBridge对象传递回调。
实现思路
首先需要在全局对象Global下新建一个Bridge对象,实现以下3个方法:
jsCallNative(method, param, callback): h5主动调用native
nativeCallback(param): native主动调用h5
listenToNativeEmitMessage(msg, callback): h5注册函数供Native调用
jsCallNative
判断是否有回调函数callback,有就生成一个sequenceId,并将id和对应callback添加进入回调函数集合responseCallbacks中
(Reason:Js函数不能跨语言传递,Native无法识别,但字符串/数字可以。使用自增长的sequenceId代替callback函数,传递给Native,Bridge内部记录一个全局对象responseCallbacks,记录sequenceId和callback函数之间的mapping关系。传递给Native的是sequenceId,Native处理完成之后,返回的时候,都带上对应的sequenceId。Bridge收到回调之后,根据sequenceId,取出对应的callback函数,然后调用。)将传参拼接转换成url,如schema://forward?param={foo:1}&sequenceId=1
-
使用一个隐藏的iframe来触发scheme
Native监听url变化,由于这里是Native的实现就不赘述了,值得注意的是这里如果有callback回调,需要带上参数sequenceId,与主动调用h5的参数是有区别的
nativeCallback
这里承接上个方法最后提到的Native主动调用h5
附上代码
可以看到,如果存在msg也就是function名,直接调用msgListenerList[msg](data);不然就是执行回调responseCallbacks[sequenceId](data),如果Native调用的api是h5没有注册的,h5页面上会有对应的错误提示'Error NativeCallback: blabla'
这个msgListenerList是哪来的呢?看最后个方法
listenToNativeEmitMessage
附上代码
listenToNativeEmitMessage: function(msg, callback) { msg && callback && msgListenerList.push({emitMessageName: callback}); }
例如Native监听到网络状态变更,大家经常会遇到,在wifi看视频时突然切成4g了需要提醒用户
Bridge.listenToNativeEmitMessage('networkStateChange', function(data){ console.log('network type: ' + data.networkType); });
结语
大概的流程就这些,自己也是初学者,查了很多资料,若有错误希望指正~