鸿蒙(HarmonyOS)性能优化—Web开发常见问题

H5页面如何与ArkTS交互(API 10)

问题现象

目前javaScriptProxy仅支持同步调用,异步调用无法获取执行结果。

解决措施

对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(`__
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值