javascript 和 native通信原理-WebViewJavascriptBridge 介绍以及简单封装

524 阅读2分钟

通信的基础:

native端到js端:native能获取到window环境,执行JS。

js端到native端:native能截获H5页面跳转,故而JS端可以通过动态创建iframe来告诉native,我发请求了。(其实就是在window下维护了一个messageQueue数组,然后js创建个iframe,告诉native,我向你发请求了,但具体是什么请求,url里面是不会体现的,需要native去遍历messageQueue数组,毕竟native能取到window环境 )。

具体实现方式:

    window.AppWebVeiw = function (callback) {
	/* 创建桥接 */
	if (window.WebViewJavascriptBridge) {
		return callback(WebViewJavascriptBridge);
	}
	if (window.WVJBCallbacks) {
		return window.WVJBCallbacks.push(callback);
	}
	window.WVJBCallbacks = [callback];
	var WVJBIframe = document.createElement('iframe');
	WVJBIframe.style.display = 'none';
	WVJBIframe.src = 'https://__bridge_loaded__';
	document.documentElement.appendChild(WVJBIframe);
	setTimeout(function () {
		document.documentElement.removeChild(WVJBIframe)
	}, 1);
    };

重点是: window.WebViewJavascriptBridge 所有的交互都是通过这个WebViewJavascriptBridge对象来完成的。

初始化的过程就是动态创建一个iframe,将iframe的src设置为https://bridge_loaded, 然后插入到页面中。前面通信基础说过,app能够截获h5跳转,当app捕获到当前URL,并且其值等于 https://bridge_loaded (当前URL是约定成俗的) ,就会注入一段自执行的代码(app那边实现并且执行),挂载WebViewJavascriptBridge到window上;

if (window.WebViewJavascriptBridge) 保证初始化只执行一次,

window.WVJBCallbacks 这个数组 用于 WebViewJavascriptBridge对象未初始化完成时保存回调函数。当我们通知APP端进行初始化,并且初始化完成之后 WebViewJavascriptBridge 会去遍历 WVJBCallbacks 里面的 回调函数,执行完毕后会执行 delete window.WVJBCallbacks

初始化完成之后我们就可以注册一些 和 app 交互的事件了

AppWebVeiw(function (b) {
   b.registerHandler('callHDBridgeHandler', function (msg, call) {
   });
    b.callHandler('registerHDBridgeHandler', {
	name: "isReady"
    }, function (r) {
	/* 询问APP是否准备完 的回调 */
	if (JSON.parse(r).name == "readyIsFinsh") GetReady = true;
    });
});

b.registerHandler 可以看到有两个参数 第一个是和 app 约定好的固定值的参数 第二个是 接收的app的回调函数 回调函数的第一个参数是app 发送的信息,第二个是给app的反馈

b.callHandler 这个多用来直接给app 发送消息 第一个参数同样是 和 app 约定好的固定参数 第二个是给app 发送的消息 第三个是app接收到消息后给的反馈结果

最后举例一些实际的应用场景 场景1:用户对页面的一些操作

AppWebVeiw(function (b){
   b.registerHandler('callHDBridgeHandler', function (msg, call) {
	if(msg.type==='isActive'){
           //用户正在浏览该页面
        }else if(msg.type==='goBack'){
           //用户点击了回退操作
        }
   });
})

场景2:获取当前用户信息

AppWebVeiw(function (b){
  b.callHandler('registerHDBridgeHandler', {name:"userInfo"},function (msg, call) {
     if(msg.accountName){
    	//获取到用户基本信息
     }	
  });
})