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

通信的基础:

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__,然后插入到页面中。前面通信基础说过,natvie能够截获h5跳转,当Native捕获到当前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){ //获取到用户基本信息 }
}); })

JSRUN前端笔记, 是针对前端工程师开放的一个笔记分享平台,是前端工程师记录重点、分享经验的一个笔记本。JSRUN前端采用的 MarkDown 语法 (极客专用语法), 这里属于IT工程师。