解决措施对javaScriptProxy和runJavaScript封装,实现JSBridge通信方案。适用于H5调用原生侧函数。使用Web组件javaScriptProxy将原生侧接口注入到H5的window对象上,通过runJavaScript接口执行JS脚本到H5中,并在回调中获取脚本执行结果。具体调用流程如下图所示:首先通过Web组件的javaScriptProxy属性,将JSBridgeHandle对象注册到H5的window上,作为H5调用原生的通道。当H5开始加载时,在onPageBegin生命周期中调用initJSBridge()方法初始化JSBridge。// javaScriptProxy对象 public get javaScriptProxy() { return { object: { call: this.call }, name: "JSBridgeHandle", methodList: ['call'], controller: this.controller, } } // 使用Web组件加载H5页面 @Component struct JsProxy { private controller: WebviewController = new WebView.WebviewController() private jsBridge: JSBridge = new JSBridge(this.controller) build() { Column(){ Web({ src: $rawfile('index.html'), controller: this.controller }) .javaScriptProxy(this.jsBridge.javaScriptProxy) .onPageBegin(() => { this.jsBridge.initJSBridge() }) } } }在initJSBridge方法中,通过webviewControll.runJavaScript()将JSBridge初始化脚本注入H5执行。当H5调用时,生成window.callID标识回调函数,将callID与调用参数使用JSBridgeHandle.call传到原生侧。通过JSBridgeCallback接收原生侧执行的结果,根据callID找到对应callback执行并且释放内存。// bridgeKey与bridgeMethod动态生成H5侧调用的入口 bridgeKey: string = 'JSBridge' bridgeMethod: string = 'call' // 初始化脚本注入H5侧 public initJSBridge() { try { this.controller.runJavaScript(` // 接收原生侧结果,执行callback function JSBridgeCallback(id, params){ window.JSBridgeMap[id](params) }; // 声明调用入口 window.${this.bridgeKey} = { ${this.bridgeMethod}(method, params, callback){ window.JSBridgeMap[id] = callback || (() => {}); JSBridgeHandle.call(method, JSON.stringify(paramsObj)); }, }`) } }JSBridgeHandle.call()是H5调用原生接口的统一入口,在该方法中根据H5调用的方法名,匹配到对应接口去调用。调用结束后通过this.callback()方法将调用结果返回H5。callback方法中使用webviewControll.runJavaScript()调用H5的JSBridgeCallback回传callID和调用结果。// call方法调用原生侧方法,接收结果 private call = (fun, params) => { try { const paramsObj = JSON.parse(params) const events = this.exposeManage.methodMap.get(fun) const results = [] events.forEach(callFun => { results.push(callFun(paramsObj.data)) }) Promise.all(results.filter(i => !!i)).then(res => { this.callback(paramsObj.callID, res.length > 1 ? res : res[0]) }) } } // 通过runJavaScript调用JSBridgeCallback执行回调 private callback(id, data) { this.controller.runJavaScript(`__JSBridgeCallback__("${id}", ${JSON.stringify(data)})`); }
解决措施
对javaScriptProxy和runJavaScript封装,实现JSBridge通信方案。适用于H5调用原生侧函数。使用Web组件javaScriptProxy将原生侧接口注入到H5的window对象上,通过runJavaScript接口执行JS脚本到H5中,并在回调中获取脚本执行结果。具体调用流程如下图所示: