HarmonyOS鸿蒙Next中h5与原生交互,在原生实现的js方法中怎么获取到webController,用于调用runJavaScript方法?

发布于 1周前 作者 songsunli 来自 鸿蒙OS

HarmonyOS鸿蒙Next中h5与原生交互,在原生实现的js方法中怎么获取到webController,用于调用runJavaScript方法? 鸿蒙端定义js方法,提供给前端调用, 之后需要通过webController的runJavaScript的方法调用h5的方法,但是JavaScriptObjTest在struct UI类外部,获取不到webController,安卓是通过handler实现,鸿蒙这边应该如何跟UI线程通信呢?

class JavaScriptObjTest {
  mUnlineLocationCallBack: string = '';

  /**
   * 系统版本
   * @param param 
   */
  jssdkCallSystemInfo(param: string) {
    PiccLog.info("js参数" + param); // isUnline = true;
    let unLineJsBirdgeReq: UnLineJsBirdgeReq = WebImp.parse(param);
    if (unLineJsBirdgeReq == null) {
      return;
    }
    switch (unLineJsBirdgeReq.method) {
      case WebviewConstant.METHOD_SYSTEMINFO_SYSTEMINFO:
        let systemInfo = WebImp.getSystemInfo();
        let loadSystemInfoScriptUrl = "javascript:" + unLineJsBirdgeReq.callback + "('"+ systemInfo +"')";
        webController.runJavaScript(loadSystemInfoScriptUrl);
        break;
    }
  }
};

@Entry
@Component
struct WebViewPage {
  webParam: WebParam = router.getParams() as WebParam;
  url: string = this.webParam.webUrl;
  webController: webview.WebviewController = new webview.WebviewController();

  build() {
    Web({ src: this.url, controller: this.webController })
      .javaScriptAccess(true)
      .javaScriptProxy({
        object: this.javascript,
        name: 'PICAppModel',
        methodList: ['jssdkCallSystemInfo'],
        controller: this.webController
      })
  }
}

更多关于HarmonyOS鸿蒙Next中h5与原生交互,在原生实现的js方法中怎么获取到webController,用于调用runJavaScript方法?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

可以对javaScriptProxy和runJavaScript封装,实现JSBridge通信方案。使用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)})`); 
}

完整demo参考链接如下:

https://gitee.com/harmonyos/codelabs/tree/master/SelectContact

更多关于HarmonyOS鸿蒙Next中h5与原生交互,在原生实现的js方法中怎么获取到webController,用于调用runJavaScript方法?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,H5与原生交互时,可以通过WebView组件的WebController来调用runJavaScript方法。具体步骤如下:

  1. 获取WebController:在原生代码中,WebView组件通过webController属性来管理Web页面的行为。你可以在WebView的初始化或回调中获取到WebController对象。

  2. 调用runJavaScript:获取到WebController后,可以直接调用runJavaScript方法执行JavaScript代码。

以下是一个简单的代码示例:

// 在ArkTS中
import web_webview from '@ohos.web.webview';

// 创建WebView组件
let webView: web_webview.WebView = new web_webview.WebView();

// 获取WebController
let webController: web_webview.WebviewController = webView.getWebviewController();

// 调用runJavaScript方法
webController.runJavaScript('alert("Hello from HarmonyOS!")');

在这个示例中,webView.getWebviewController()方法用于获取WebController,然后通过runJavaScript方法执行JavaScript代码。

需要注意的是,runJavaScript方法通常在页面加载完成后调用,以确保JavaScript代码能够在正确的上下文中执行。

总结:在HarmonyOS鸿蒙Next中,通过WebView组件的WebController可以调用runJavaScript方法,实现H5与原生交互。

在HarmonyOS鸿蒙Next中,若要在原生实现的JS方法中获取WebController以调用runJavaScript方法,可以通过WebView组件提供的getWebController方法获取WebController实例。具体步骤如下:

  1. 在原生代码中,通过WebView组件的getWebController方法获取WebController实例。
  2. 在JS中调用原生方法时,将WebController实例作为参数传递给JS方法。
  3. 在JS方法中,使用传递的WebController实例调用runJavaScript方法。

示例代码:

WebView webView = findComponentById(ResourceTable.Id_webview);
WebController webController = webView.getWebController();
webController.runJavaScript("yourJavaScriptCode");

确保在JS中正确接收并使用WebController实例。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!