方舟web使用及数据双向通信

一、需解决的问题:

  1. 怎么加载本地html文件;
  2. 加载成功后应用端怎么调用js中的方法;
  3. js中怎么将数据传给应用端、或js端怎么调用应用端的数据。 参考地址:

二、怎么加载本地html文件

typescript 复制代码
import { webview } from "@kit.ArkWeb";

@Component
export struct MyPage {
  controller: webview.WebviewController = new webview.WebviewController();
  
  build() {
    Column() {
      Web({ src: $rawfile("map/index.html"), controller: this.controller })
        .onPageEnd(() => {
          // 推荐在此loadUrl、设置自定义用户代理、注入JS对象等
          this.controller.runJavaScript("setLatLonCenterNoMark(112.12853720100244,32.014796804669224,'8')");
          this.controller.runJavaScript("addYhdMark('YHD',112.12853720100244,32.014796804669224,'测试名称','#00ff00')");
        })
    }
  }
}

三、加载成功后应用端怎么调用js中的方法

可通过:

kotlin 复制代码
  this.controller.runJavaScript("")

直接引用js中的方法。

四、js中怎么将数据传给应用端、或js端怎么调用应用端的数据

有两种方法,我理解的分为:注册型与端口监听型,下面说说这两种方法的具体实现

1、注册型

应用侧代码:

scala 复制代码
import { webview } from "@kit.ArkWeb";
import { hilog } from "@kit.PerformanceAnalysisKit";

class TestClass {
  constructor() {
  }

  test(name:string): string {
    hilog.info(0,"测试",name)
    return 'ArkTS Hello World!';
  }
}
@Component
export struct MyPage {
  controller: webview.WebviewController = new webview.WebviewController();
  // 声明需要注册的对象
  @State testObj: TestClass = new TestClass();

  build() {
    Column() {
      Web({ src: $rawfile("map/index.html"), controller: this.controller })
        .onPageEnd(() => {
          // 推荐在此loadUrl、设置自定义用户代理、注入JS对象等
          this.controller.runJavaScript("setLatLonCenterNoMark(112.12853720100244,32.014796804669224,'8')");
          this.controller.runJavaScript("addYhdMark('YHD',112.12853720100244,32.014796804669224,'测试名称','#00ff00')");
        })
          // 将对象注入到web端
        .javaScriptProxy({
          object: this.testObj,
          name: "testObjName",
          methodList: ["test"],
          controller: this.controller,
          // 可选参数
          asyncMethodList: [],
          permission: '{"javascriptProxyPermission":{"urlPermissionList":[{"scheme":"resource","host":"rawfile","port":"","path":""},' +
            '{"scheme":"e","host":"f","port":"g","path":"h"}],"methodList":[{"methodName":"test","urlPermissionList":' +
            '[{"scheme":"https","host":"xxx.com","port":"","path":""},{"scheme":"resource","host":"rawfile","port":"","path":""}]},' +
            '{"methodName":"test11","urlPermissionList":[{"scheme":"q","host":"r","port":"","path":"t"},' +
            '{"scheme":"u","host":"v","port":"","path":""}]}]}}'
        })
    }
  }
}

js端调用应用端方法

2、监听型

主要是通过创建2个port,一个放在应用端使用,一个放在js端使用来达到互相通信

应用侧代码

typescript 复制代码
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { webview } from '@kit.ArkWeb';

@Component
export struct TxlPage {
  controller: webview.WebviewController = new webview.WebviewController();
  //第二种方法
  ports: webview.WebMessagePort[] = [];
  @State receivedFromHtml: string = 'Display received message send from HTML';
  @State sendFromEts: string = 'Send this message from ets to HTML';

  build() {
    Column() {
      Web({ src: $rawfile("map/index.html"), controller: this.controller })
        .onPageEnd(() => {
         // 推荐在此loadUrl、设置自定义用户代理、注入JS对象等
        this.controller.runJavaScript("setLatLonCenterNoMark(112.12853720100244,32.014796804669224,'8')");
        this.controller.runJavaScript("addYhdMark('YHD',112.12853720100244,32.014796804669224,'测试名称','#00ff00')");

          try {
            // 1、创建两个消息端口。
            this.ports = this.controller.createWebMessagePorts();
            if (this.ports && this.ports[0] && this.ports[1]) {
              // 2、在应用侧的消息端口(如端口1)上注册回调事件。
              this.ports[1].onMessageEvent((result: webview.WebMessage) => {
                let msg = 'Got msg from HTML:';
                if (typeof (result) === 'string') {
                  hilog.warn(0,'测试',`received string message from html5, string is: ${result}`);
                  msg = msg + result;
                } else if (typeof (result) === 'object') {
                  if (result instanceof ArrayBuffer) {
                    hilog.warn(0,'测试1',`received arraybuffer from html5, length is: ${result.byteLength}`);
                    msg = msg + 'length is ' + result.byteLength;
                  } else {
                    hilog.info(1,"",'not support');
                  }
                } else {
                  hilog.info(1,"",'not support');
                }
                this.receivedFromHtml = msg;
              })
              // 3、将另一个消息端口(如端口0)发送到HTML侧,由HTML侧保存并使用。
              this.controller.postMessage('__init_port__', [this.ports[0]], '*');
            } else {
              console.error(`ports is null, Please initialize first`);
            }
          } catch (error) {
            hilog.info(1,"",'初始化出错');
            console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
          }
      })
    }
  }
}

js端

csharp 复制代码
//监听应用端发送过来的消息
var h5Port;
window.addEventListener('message', function (event) {
    if (event.data === '__init_port__') {
        if (event.ports[0] !== null) {
            h5Port = event.ports[0]; // 1. 保存从应用侧发送过来的端口。
            h5Port.onmessage = function (event) {
                // 2. 接收ets侧发送过来的消息。
                var msg = 'Got message from ets:';
                var result = event.data;
                if (typeof(result) === 'string') {
                    clearFeaturesByLayerName("select_point_name");
                    alert('received string message from html5, string is: ${result}');
                    msg = msg + result;
                } else if (typeof(result) === 'object') {
                    if (result instanceof ArrayBuffer) {
                        alert('received arraybuffer from html5, length is: ${result.byteLength}');
                        msg = msg + 'length is ' + result.byteLength;
                    } else {
                        alert('not support');
                    }
                } else {
                    alert('not support');
                }
            }
        }
    }
})

回传给应用端

觉得写得好麻烦点赞鼓励下,谢谢

相关推荐
90后的晨仔1 小时前
HarmonyOS 多模块项目中的公共库治理与最佳实践
harmonyos
lili-felicity5 小时前
React Native 鸿蒙跨平台开发:LayoutAnimation 实现鸿蒙端按钮点击的缩放反馈动画
react native·react.js·harmonyos
哈__7 小时前
React Native 鸿蒙跨平台开发:Dimensions 屏幕尺寸获取
react native·华为·harmonyos
奋斗的小青年!!7 小时前
Flutter跨平台开发适配OpenHarmony:手势识别实战应用
flutter·harmonyos·鸿蒙
搬砖的kk8 小时前
Cordova 适配鸿蒙系统(OpenHarmony) 全解析:技术方案、环境搭建与实战开发
华为·开源·harmonyos
不爱吃糖的程序媛8 小时前
OpenHarmony 通用C/C++三方库 标准化鸿蒙化适配
c语言·c++·harmonyos
程序猿追8 小时前
鸿蒙PC应用开发深度实战:一次开发、多端适配的沉浸式音乐播放器迁移实践
华为·harmonyos
行者969 小时前
Flutter跨平台开发:安全检测组件适配OpenHarmony
flutter·harmonyos·鸿蒙
小雨下雨的雨10 小时前
Flutter 框架跨平台鸿蒙开发 —— GridView 控件之多维网格美学
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨10 小时前
Flutter跨平台开发实战: 鸿蒙与循环交互艺术:无限循环的 Banner 引擎
flutter·ui·华为·交互·harmonyos·鸿蒙系统