在HarmonyOS上实现ArkTS与H5的交互
介绍
本篇Codelab主要介绍H5如何调用原生侧相关功能,并在回调中获取执行结果。以“获取通讯录”为示例分步讲解JSBridge桥接的实现。
相关概念
Web组件:提供具有网页显示能力的Web组件。
@ohos.web.webview:提供web控制能力。
完整示例
源码下载
环境搭建
我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。
软件要求
DevEco Studio版本:DevEco Studio 3.1 Release。
HarmonyOS SDK版本:API version 9。
硬件要求
设备类型:华为手机或运行在DevEco Studio上的华为手机设备模拟器。
HarmonyOS系统:3.1.0 Developer Release。
环境搭建
安装DevEco Studio,详情请参考下载和安装软件。
设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境。
开发者可以参考以下链接,完成设备调试的相关配置:使用真机进行调试
代码结构解读
本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在源码下载或gitee中提供。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ├──entry/src/main/ets // 代码区 │ ├──common // 公共代码区 │ │ ├──constants // 公共常量 │ │ │ ├──CodeConstant.ets // 异步脚本模板 │ │ │ └──CommonConstant.ets // 公共常量和样式常量 │ │ └──utils // 工具类 │ │ ├──JsBridge.ets // 桥接类 │ │ └──Logger.ets // 日志类 │ ├──entryability │ │ └──EntryAbility.ets // 程序入口 │ ├──pages │ │ └──SelectContact.ets // 主页面 │ └──viewmodel // 项目所需数据类型定义 │ ├──JavaScriptItem.ets // javaScriptProxy数据格式 │ └──ParamsItem.ets // 回调参数数据格式 └──entry/src/main/resources // 资源入口(rawfile文件夹中存放html) └──rawfile ├──js │ └──mainPage.js // H5调用函数文件 ├──css │ └──main.css // H5样式文件 └──MainPage.html // H5页面 |
ArkTS侧与H5的交互
1. 首先在开发H5页面(输入框和金额选择部分)前需要实现JSBridge桥接打通两侧的交互。开发者可以在ArkTS侧定义一个JSBridge类,在类中封装call方法以及initJsBridge方法。
2. 准备异步执行脚本,在脚本中声明一个JSBridgeMap、JSBridgeCallback方法与ohosCallNative对象。并通过runJavaScript在H5端注册ohosCallNative。
3. 通过Web组件的javaScriptProxy属性将ArkTS侧的call方法以及JSBridgeHandle注册到H5。H5侧调用ohosCallNative对象中的callNative方法,传递func、params以及callback回调。在callNative中保存callback回调。并调用JSBridgeHandle的call方法。
4. ArkTS侧执行完毕。最后调用runJavaScript方法执行callback,H5侧接收异步回调数据。
4.1 初始化JSBridge
在initJSBridge方法中,通过webviewControll.runJavaScript()将JSBridge初始化脚本注入H5执行。其中callID用来标识H5回调;JSBridgeCallback方法用来执行H5侧回调;window.ohosCallNative对象给H5侧提供调用函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // CodeConstant.ets /** * 异步执行脚本 */ export const code = ` const JSBridgeMap = {}; let callID = 0; // 执行H5回调函数 function JSBridgeCallback (id, params ) { JSBridgeMap[id]( params ); JSBridgeMap[id] = null ; delete JSBridgeMap[id]; } // 在window中声明callNative方法供H5调用 window.ohosCallNative = { callNative(method, params , callback) { const id = callID++; const paramsObj = { callID: id, data: params || null } JSBridgeMap[id] = callback || (() => {}); JSBridgeHandle.call(method, JSON.stringify(paramsObj)); } } `; |
4.2 javaScriptProxy注入
通过Web组件的javaScriptProxy属性,将JSBridgeHandle对象注册到H5侧的window上,作为H5调用原生的通道。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | // JsBridge.ets export default class JsBridge { /** * 注入JavaScript对象到window对象中 * * @returns javaScriptProxy object */ get javaScriptProxy(): JavaScriptItem { return { object : { call: this .call }, name: "JSBridgeHandle" , methodList: [ 'call' ], controller: this .controller } as JavaScriptItem; } } // SelectContact.ets @Entry @Component struct SelectContact { webController: WebView.WebviewController = new WebView.WebviewController(); private jsBridge: JSBridge = new JSBridge( this .webController); build() { Column() { Web({ src: $rawfile( 'MainPage.html' ), controller: this .webController }) .javaScriptAccess( true ) .javaScriptProxy( this .jsBridge.javaScriptProxy) ... } ... } } |
4.3 call方法及callback回调
call方法作为H5调用原生侧接口的统一入口,在该方法中根据H5调用的方法名,匹配到对应的接口后调用,调用结束后通过this.callback()方法,将调用结果回传到H5。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // JsBridge.ets /** * 定义桥接类 */ export default class JsBridge { /** * 将ArkTS侧数据传递给call方法 */ call = (func: string , params : string ): void => { const paramsObject: ParamsItem = JSON.parse( params ); switch (func) { case 'chooseContact' : result = this .chooseContact(); break ; default : break ; } result.then((data: string ) => { this .callback(paramsObject?.callID, data); }) } /** * 将ArkTS侧数据传递到H5 */ callback = (id: number, data: string ): void => { this .controller.runJavaScript(`JSBridgeCallback( "${id}" , ${JSON.stringify(data)})`); } } |
4.4 H5调用ArkTS
实现了上述桥接逻辑后,在H5侧只需要调用ohosCallNative方法,将函数名以及回调函数传递到ArkTS。
1 2 3 4 5 6 | // mainPage.js function chooseContact() { window.ohosCallNative.callNative( 'chooseContact' , {}, (data) => { ... }); } |
总结
您已经完成了本次Codelab的学习,并了解到以下知识点:
1. ArkTS侧如何使用桥接通道提供给H5调用方法。
2. H5如何接收ArkTS侧的异步数据。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!