HarmonyOS Web js与原生交互

webView.addJavascriptObject(new JsApi(), null);
webView.addJavascriptInterface(this, "xxx");

@JavascriptInterface
public void h5Share(Object shareBodyString) { // h5页面 长按显示分享 回调
  showShareView(shareBodyString);
}

Java代码如上,在HarmonyOS 上

class TestObj {
  constructor() {
  }

  h5Share(shareBodyString: ESObject) {
    Log.info(`-----> webPage javaScriptProxy h5Share: ${shareBodyString?.toString()}}`)
    ToastUtil.showToast('js调用了h5分享')
    return ''
  }
}

testObj = new TestObj();//js和原生交互

.javaScriptAccess(true)
  .javaScriptProxy({
    object: this.testObj,
    name: "objName",
    methodList: ["h5Share", "toString"],
    asyncMethodList: ["asyncTest"],
    controller: this.controller,
  })

没有效果

HarmonyOS
1天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
put_get

使用JsBridge实现,请参考:

index.ets

import { JsBridge } from '../common/JsBridge';
import { WebViewControllerProxy } from '@hzw/ohos-dsbridge';

@Entry
@Component
export struct WebJsPage {
  @State message: string = "";
  private controller: WebViewControllerProxy = WebViewControllerProxy.createController();

  aboutToAppear(): void {
    this.controller.addJavascriptObject(new JsBridge())
  }

  build() {
    Column() {
      Text(this.message)
      Web({ src: $rawfile("webViewHtml/Page.html"), controller: this.controller.getWebViewController() })
        .javaScriptAccess(true)
        .javaScriptProxy(this.controller.getJavaScriptProxy())
        .onAlert((event) => {
          return false
        })
        .width("100%")
        .height('50%')
      Button("调用js函数-异步")
        .margin({ top: 10 })
        .onClick(() => {
          this.controller.callJs("showAlertAsync", [1, 2, '666'], (v: string) => {
            this.message = v + ""
          })
        })
    }
    .width("100%")
    .height('100%')

  }
}

JsBridge.ets

import { LogUtils } from '@hzw/ohos-dsbridge/src/main/ets/utils/LogUtils'
import { CompleteHandler, JavaScriptInterface } from '@hzw/ohos-dsbridge'

export class JsBridge{

  private cHandler: CompleteHandler | undefined = undefined

  /**
   * 同步
   * @param p
   * @returns
   */
  @JavaScriptInterface(false)
  testSync(p: string): string {
    LogUtils.d("testSync: " + JSON.stringify(p))
    return "hello native"
  }

  /**
   * 异步
   * @param p
   * @param handler
   */
  @JavaScriptInterface()
  testAsync(p: string, handler: CompleteHandler) {
    LogUtils.d("testAsync: " + JSON.stringify(p))
    this.cHandler = handler
  }

  @JavaScriptInterface()
  testClick(p: string, handler: CompleteHandler) {
    // p 为 h5 返回的数据
    this.cHandler = handler
    this.cHandler.complete("我是HarmonyOS侧消息");
  }
}

page.html

<html>
<head>
    <meta content="text/html; charset=utf-8" http-equiv="content-type">
    <title>
        js调用java
    </title>
    <script src="./dsBridge.js" ></script>
</head>

<body>
<h1 id="show">1111</h1>
<button style="height:100px;width:200px;font-size:20px" id="enter" onclick="testClick()">获取HarmonyOS侧</button>
</body>
<script>
    dsBridge.registerAsyn('showAlertAsync', function (a, b, c, callback) {
        callback('我是js侧消息', false)
    })

    function testClick() {
    dsBridge.call('testClick', "hello", (responseData) => {
            document.getElementById("show").innerHTML =  responseData
        })
    }
</script>
</html>

html引入的dsBridge.js代码:

https://cdn.jsdelivr.net/npm/m-dsbridge/dsBridge.js
    // @ts-nocheck
    const bridge = {
        call: function (method, args, callback) {
            let params = {data: args === undefined ? null : args}
            if (callback != null && typeof callback == 'function') {
                if (!window.callID) {
                    window.callID = 0
                }
                const callName = "dscall" + (window.callID++)
                window[callName] = callback
                params["_dscbstub"] = callName
            }
            let paramsStr = JSON.stringify(params)
            let res = ""
            if (window._dsbridge){
                res = window._dsbridge.call(method, paramsStr)
            }
            return JSON.parse(res).data
        },
        register: function (method, func, async) {
            if (window._dsaf && window._dsf){
                let obj = async ? window._dsaf : window._dsf
                obj[method] = func
                if (typeof func == "object") {
                    obj._obs[method] = func;
                } else {
                    obj[method] = func;
                }
            }

        },
        registerAsyn: function (method, func) {
            this.register(method, func, true)
        },
        registerAsync: function (method, func) {
            this.register(method, func, true)
        },
        hasNativeMethod: function (method) {
            return this.call("_dsb.hasNativeMethod", {name: method})
        },
        close: function () {
            this.call("_dsb.closePage")
        },
    };

(function (){
    const manager = {
        _dsf: {
            _obs: {}
        },
        _dsaf: {
            _obs: {}
        },
        dsBridge: bridge,
        close: function () {
            bridge.close()
        },
        _handleMessageFromNative: function (info) {

            let arg = JSON.parse(info.data);
            let ret = {
                id: info.callbackId, complete: true
            }
            let f = this._dsf[info.method];
            let af = this._dsaf[info.method]
            let callSyn = function (f, ob) {
                ret.data = f.apply(ob, arg)
                bridge.call("_dsb.returnValue", ret)
            }
            let callAsync = function (f, ob) {
                arg.push(function (data, complete) {
                    ret.data = data;
                    ret.complete = complete !== false;
                    bridge.call("_dsb.returnValue", ret)
                })
                f.apply(ob, arg)
            }
            if (f) {
                callSyn(f, this._dsf);
            } else if (af) {
                callAsync(af, this._dsaf);
            }else {
                // namespace
                let name = info.method.split('.');
                if (name.length<2) return;
                let method=name.pop();
                let namespace=name.join('.')
                let obs = this._dsf._obs;
                let ob = obs[namespace] || {};
                let m = ob[method];
                if (m && typeof m == "function") {
                    callSyn(m, ob);
                    return;
                }
                obs = this._dsaf._obs;
                ob = obs[namespace] || {};
                m = ob[method];
                if (m && typeof m == "function") {
                    callAsync(m, ob);
                    return;
                }
            }
        }
    }

    for (let attr in manager) {
        window[attr] = manager[attr]
        console.log(attr)
    }

    dsBridge.register("_hasJavascriptMethod", (method) => {
        const name = method.split('.')
        if (name.length < 2) {
            return !!(_dsf[name] || _dsaf[name])
        } else {
            // namespace
            let method = name.pop()
            let namespace = name.join('.')
            let ob = _dsf._obs[namespace] || _dsaf._obs[namespace]
            return ob && !!ob[method]
        }
    })

})();

// module.exports = dsBridge;
// export default dsBridge;
分享
微博
QQ
微信
回复
1天前
相关问题
HarmonyOS 原生js交互
247浏览 • 1回复 待解决
HarmonyOS web原生交互
33浏览 • 1回复 待解决
HarmonyOS WebViewjs交互
82浏览 • 1回复 待解决
HarmonyOS webjs交互
204浏览 • 1回复 待解决
HarmonyOS WebJavaScript交互
39浏览 • 1回复 待解决
HarmonyOS 系统web交互
22浏览 • 1回复 待解决
HarmonyOS web原生交互的demo
80浏览 • 1回复 待解决
HarmonyOS web组件和js交互
159浏览 • 1回复 待解决
HarmonyOS web原生和H5如何交互
559浏览 • 1回复 待解决
HarmonyOS webH5交互
739浏览 • 1回复 待解决
ArkTS/js怎样C++进行交互
268浏览 • 1回复 待解决
HarmonyOS webH5两端数据交互
924浏览 • 1回复 待解决
HarmonyOSweb内嵌vue页面的交互问题
593浏览 • 1回复 待解决
HarmonyOS H5和原生交互
31浏览 • 1回复 待解决
HarmonyOS web交互示例
23浏览 • 1回复 待解决