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