本文旨在深入探讨华为鸿蒙HarmonyOS Next系统(截止目前API12)的技术细节,基于实际开发实践进行总结。
主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。
本文为原创内容,任何形式的转载必须注明出处及原作者。

在鸿蒙开发中,前端页面(HTML)有时候需要调用应用侧(ArkTS)的函数,例如获取设备信息、调用本地服务、进行复杂的业务逻辑处理等。那么,如何实现前端页面轻松调用 ArkTS 函数呢?

JavaScriptProxy:前端页面的“万能遥控器”

为了实现前端页面调用 ArkTS 函数,我们可以使用 JavaScriptProxy。JavaScriptProxy 是 ArkWeb 提供的一种机制,它允许我们将 ArkTS 对象注册到前端页面,并在前端页面中调用这些对象的函数。
我们可以使用 javaScriptProxy()registerJavaScriptProxy() 接口将 ArkTS 对象注册到前端页面。

  • javaScriptProxy() 接口: 在 Web 组件初始化时调用,将对象注入到前端页面。
  • registerJavaScriptProxy() 接口: 在 Web 组件初始化完成后调用,将对象注册到前端页面。

    示例代码:前端页面调用 ArkTS 函数

    下面,我们通过一个示例代码来演示如何将 ArkTS 函数注册到前端页面,并在前端页面中调用这些函数。
    应用侧代码(ArkTS)

    import { webview } from '@kit.ArkWeb';
    import { BusinessError } from '@kit.BasicServicesKit';
    class testClass {
      constructor() {
      }
      test(): string {
    return 'ArkTS Hello World!';
      }
      toString(param: string): void {
    console.log('Web Component toString' + param);
      }
    }
    @Entry
    @Component
    struct WebComponent {
      webviewController: webview.WebviewController = new webview.WebviewController();
      // 声明需要注册的对象
      @State testObj: testClass = new testClass();
      build() {
    Column() {
      // Web组件加载本地index.html页面
      Web({ src: $rawfile('index.html'), controller: this.webviewController})
        // 将对象注入到web端
        .javaScriptProxy({
          object: this.testObj,
          name: "testObjName",
          methodList: ["test", "toString"],
          controller: this.webviewController,
          // 可选参数
          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":""}]}]}}'
        })
    }
      }
    }

    前端页面代码(HTML)

    <!-- index.html -->
    <!DOCTYPE html>
    <html>
    <body>
    <button type="button" onclick="callArkTS()">Click Me!</button>
    <p id="demo"></p>
    <script>
    function callArkTS() {
        let str = testObjName.test();
        document.getElementById("demo").innerHTML = str;
        console.info('ArkTS Hello World! :' + str);
        testObjName.toString(str);
    }
    </script>
    </body>
    </html>

    权限配置:确保应用安全

    为了确保应用安全,我们可以配置 JavaScriptProxy 的权限。权限配置是一个 JSON 字符串,包含对象级权限和方法级权限。

  • 对象级权限: 指定哪些 URL 可以访问该对象的所有方法。
  • 方法级权限: 指定哪些 URL 可以访问该对象的特定方法。
    通过配置权限,我们可以控制前端页面调用 ArkTS 函数的范围,防止恶意攻击。
    权限配置示例

    {
      "javascriptProxyPermission": {
    "urlPermissionList": [
      {
        "scheme": "resource",    // 精确匹配,不能为空
        "host": "rawfile",       // 精确匹配,不能为空
        "port": "",              // 精确匹配,为空不检查
        "path": ""               // 前缀匹配,为空不检查
      },
      {
        "scheme": "https",       // 精确匹配,不能为空
        "host": "xxx.com",       // 精确匹配,不能为空
        "port": "8080",          // 精确匹配,为空不检查
        "path": "a/b/c"          // 前缀匹配,为空不检查
      }
    ],
    "methodList": [
      {
        "methodName": "test",
        "urlPermissionList": [   // Method级权限
          {
            "scheme": "https",   // 精确匹配,不能为空
            "host": "xxx.com",   // 精确匹配,不能为空
            "port": "",          // 精确匹配,为空不检查
            "path": ""           // 前缀匹配,为空不检查
          },
          {
            "scheme": "resource",// 精确匹配,不能为空
            "host": "rawfile",   // 精确匹配,不能为空
            "port": "",          // 精确匹配,为空不检查
            "path": ""           // 前缀匹配,为空不检查
          }
        ]
      },
      {
        "methodName": "test11",
        "urlPermissionList": [   // Method级权限
          {
            "scheme": "q",       // 精确匹配,不能为空
            "host": "r",         // 精确匹配,不能为空
            "port": "",          // 精确匹配,为空不检查
            "path": "t"          // 前缀匹配,为空不检查
          },
          {
            "scheme": "u",       // 精确匹配,不能为空
            "host": "v",         // 精确匹配,不能为空
            "port": "",          // 精确匹配,为空不检查
            "path": ""           // 前缀匹配,为空不检查
          }
        ]
      }
    ]
      }
    }

    复杂类型传递:不只是基础数据

    JavaScriptProxy 不仅支持传递基础数据类型,例如字符串、数字等,还支持传递复杂类型,例如数组、对象等。
    示例

  • 传递数组

    class testClass {
      constructor() {
      }
      test(): Array<number> {
    return [1, 2, 3, 4]
      }
      toString(param: string): void {
    console.log('Web Component toString' + param);
      }
    }
  • 传递对象

    class student {
      name: string = '';
      age: string = '';
    }
    class testClass {
      constructor() {
      }
      test(): student {
    let st: student = { name: "jeck", age: "12" };
    return st;
      }
      toString(param: string): void {
    console.log('Web Component toString' + param);
      }
    }

    Promise 场景:异步调用

    JavaScriptProxy 也支持异步调用,可以使用 Promise 来处理异步结果。
    示例

  • 应用侧返回 Promise

    class testClass {
      constructor() {
      }
      test(): Promise<string> {
    let p: Promise<string> = new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('执行完成');
        resolve('suc');
      }, 10000);
    });
    return p;
      }
      toString(param: string): void {
    console.log(" " + param);
      }
    }
  • 前端页面处理 Promise

    function callArkTS() {
      testObjName.test().then((param)=>{testObjName.toString(param)}).catch((param)=>{testObjName.toString(param)})
    }

    通过使用 JavaScriptProxy,我们可以轻松实现前端页面调用 ArkTS 函数,让开发变得更加灵活和高效。它支持传递各种类型的数据,并支持异步调用,满足了各种复杂的开发需求。


SameX
1 声望2 粉丝