本文旨在深入探讨华为鸿蒙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 函数,让开发变得更加灵活和高效。它支持传递各种类型的数据,并支持异步调用,满足了各种复杂的开发需求。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。