hybrid设计之Native和H5交互原理

本人最近在研究hybrid的实现原理且读了一些源码 仅限前端js的 因此非前端或非hybrid模式的童鞋能够绕过~javascript

首先简介下url scheme

手机APP都有一个沙盒,能够注册本身的URL Scheme。咱们能够经过系统的OpenURL来打开该app,并能够传递一些参数。例如:
CtripWireless://打开携程App
weixin:// 打开微信前端

目前大部分hybrid设计都是沿用JSBridge的,在不一样的平台经过不一样的native层实现,在各自平台下完成编译。java

什么是JSBridge?

顾名思义,JSBridge就是定义Native和JS的通讯,Native只经过一个固定的桥对象调用JS,JS也只经过固定的桥对象调用Native,基本原理是:git

H5->经过某种方式触发一个url->Native捕获到url,进行分析->原生作处理->Native调用H5的JSBridge对象传递回调。github

图片描述

实现思路

首先须要在全局对象Global下新建一个Bridge对象,实现如下3个方法:web

  1. jsCallNative(method, param, callback): h5主动调用native
  2. nativeCallback(param): native主动调用h5
  3. listenToNativeEmitMessage(msg, callback): h5注册函数供Native调用

jsCallNative

  1. 判断是否有回调函数callback,有就生成一个sequenceId,并将id和对应callback添加进入回调函数集合responseCallbacks中

(Reason:Js函数不能跨语言传递,Native没法识别,但字符串/数字能够。使用自增加的sequenceId代替callback函数,传递给Native,Bridge内部记录一个全局对象responseCallbacks,记录sequenceId和callback函数之间的mapping关系。传递给Native的是sequenceId,Native处理完成以后,返回的时候,都带上对应的sequenceId。Bridge收到回调以后,根据sequenceId,取出对应的callback函数,而后调用。)api

  1. 将传参拼接转换成url,如schema://forward?param={foo:1}&sequenceId=1
  2. 使用一个隐藏的iframe来触发scheme

    图片描述

  3. Native监听url变化,因为这里是Native的实现就不赘述了,值得注意的是这里若是有callback回调,须要带上参数sequenceId,与主动调用h5的参数是有区别的

图片描述

nativeCallback

这里承接上个方法最后提到的Native主动调用h5
图片描述微信

附上代码网络

图片描述

能够看到,若是存在msg也就是function名,直接调用msgListenerList[msg](data);否则就是执行回调responseCallbacks[sequenceId](data),若是Native调用的api是h5没有注册的,h5页面上会有对应的错误提示'Error NativeCallback: blabla'app

这个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);
});

结语

大概的流程就这些,本身也是初学者,查了不少资料,如有错误但愿指正~
附上个人代码: webview-js-bridge

相关文章
相关标签/搜索