介绍
本篇 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 中提供。
├──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 侧提供调用函数。
// 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 调用原生的通道。
// jsbridge.etsexport 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@componentstruct 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。
// 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。
// mainpage.jsfunction choosecontact() {window.ohoscallnative.callnative('choosecontact', {}, (data) => {...});}
总结
您已经完成了本次 codelab 的学习,并了解到以下知识点:
1. arkts 侧如何使用桥接通道提供给 h5 调用方法。
2. h5 如何接收 arkts 侧的异步数据。
 
             我要评论
我要评论 
                                             
                                             
                                            
发表评论