鸿蒙开发黑科技:前端页面轻松调用 ArkTS 函数 原创

SameX
发布于 2024-10-17 13:48
浏览
1收藏

本文旨在深入探讨华为鸿蒙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 函数,让开发变得更加灵活和高效。它支持传递各种类型的数据,并支持异步调用,满足了各种复杂的开发需求。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
标签
已于2024-10-17 13:48:28修改
1
收藏 1
回复
举报
3条回复
按时间正序
/
按时间倒序
精灵鼠小妹
精灵鼠小妹

黑科技,酷

回复
2024-10-17 18:00:05
shizhi02
shizhi02

哈哈,带感

回复
2024-10-18 11:38:03
awa_Liny
awa_Liny

有用!谢谢!

回复
2024-10-19 23:42:58
回复
    相关推荐