我们的APP是典型的混合开发APP,内嵌的前端页面都是内嵌的。前端页面要和原来的效果差不多,调用一些native方法是难免的。jsBridge是js和native通信的桥梁。本文不谈概念性的东西,而是通过分析我们项目中jsBridge的源码,从前端的角度大致了解它是如何实现的。先来看看js的调用方式。js如何调用native方法?首先,它会在初始化时调用window.WebViewJavascriptBridge.init方法:window.WebViewJavascriptBridge.init()然后如果要调用native方法,可以使用如下函数:functionnative(funcName,args={},callbackFunc,errorCallbackFunc){//检查参数是否合法!args.length){args=JSON.stringify(args);}else{thrownewError('参数不符合规范');}//判断是否为手机环境if(getIsMobile()){//调用window.WebViewJavascriptBridge对象的callHandler方法window.WebViewJavascriptBridge.callHandler(funcName,args,(res)=>{res=JSON.parse(res);if(res.code===0){returncallbackFunc(res);}else{returnerrorCallbackFunc(res);}});}}只需传入方法名、参数和要调用的回调,它首先检查参数,然后调用window.WebViewJavascriptBridge.callHandler方法还可以为原生调用提供回调:window.WebViewJavascriptBridge.registerHandler(funcName,callbackFunc);接下来我们看一下window.WebViewJavascriptBridge对象是什么。AndroidWebViewJavascriptBridge.js文件是一个自执行函数。首先,定义一些变量://定义变量varmessagingIframe;varsendMessageQueue=[];//发送消息的队列varreceiveMessageQueue=[];//接收消息的队列varmessageHandlers={};//消息处理器varCUSTOM_PROTOCOL_SCHEME='yy';//自定义协议varQUEUE_HAS_MESSAGE='__QUEUE_MESSAGE__/';varresponseCallbacks={};//响应回调varuniqueId=1;简单的按照我翻译出来的变量名,具体使用接下来会分析。接下来,定义WebViewJavascriptBridge对象:可以看到是一个普通对象,上面Mounted了一些方法,具体方法暂时不看,继续往下:vardoc=document;_createQueueReadyIframe(doc);调用_createQueueReadyIframe方法:function_createQueueReadyIframe(doc){messagingIframe=doc.createElement('iframe');messagingIframe.style.display='无';doc.documentElement.appendChild(messagingIframe);}这个方法很简单,就是创建一个隐藏的iframe插入到页面中,继续往下://创建一个事件类型(基本事件模块)事件(Event)对象varreadyEvent=doc.createEvent('Events');//定义事件名称为WebViewJavascriptBridgeReadyreadyEvent.initEvent('WebViewJavascriptBridgeReady');//通过文档触发事件doc.dispatchEvent(readyEvent);在这里定义创建了一个自定义事件并直接派发它。其他地方可以像监听原生事件一样监听事件:document.addEventListener('WebViewJavascriptBridgeReady',function(){console.log(window.WebViewJavascriptBridge)},false);我理解这里的用处是,如果jsBridge文件是在其他代码之后引入的,需要保证前面的代码能够知道window.WebViewJavascriptBridge对象什么时候可用。如果指定jsBridge必须先引入,那么就不需要这个处理了。自执行功能到这里就结束了。接下来看初始的init方法:}//调用init时没有传递参数,所以messageHandler=undefinedWebViewJavascriptBridge._messageHandler=messageHandler;//当前receiveMessageQueue只是一个空数组varreceivedMessages=receiveMessageQueue;receiveMessageQueue=null;对于(vari=0;i
