查看: 110|回复: 0

鸿蒙ArkTS迁移JSBridge:Web组件拦截注入与闭包改造

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在 Android、iOS 和 HarmonyOS 并存的移动端项目中,APP 内嵌 H5 是减少多端维护成本的常见做法。但 H5 不能直接访问相机、麦克风、设备信息等原生能力,必须在 APP 与 H5 之间建立双向通信桥。JSBridge 就是这类桥:它定义 JS 接口与 Native 接口,让 H5 调 APP 原生方法、APP 回调 H5 方法,并完成数据传递。

开源 JSBridge 中,WebViewJavascriptBridge(github.com/marcuswestin/WebViewJavascriptBridge,14.3K stars、3K forks)和 JsBridge(github.com/lzyzsd/JsBridge 或 github.com/happydog-intj/JsBridge,9.9K stars、2K forks)较常见。这两个框架过去主要面向 Android;目前 WebViewJavascriptBridge 已有鸿蒙版本,但 JsBridge 还没有合适的鸿蒙版本。因此,本文的实践目标是把 Android 版 JsBridge 改造成 HarmonyOS 版,使同一套 H5 能继续以原有协议对接鸿蒙 APP。

一、迁移前先看源码规模与改造重点

虽然 AI 工具能帮助把 Android 代码转换为鸿蒙代码,但后续调试与适配仍要人工完成,尤其是 Web 容器回调、对象注入和语言语法差异。JsBridge 1.0.4 版只有 8 个代码文件,去掉简单接口与实体类定义后,真正需要大幅改写的文件约两三个。改造重点可以归为三类:系统 SDK 的 API 替换、工具库替换、ArkTS 语法与组件模型适配。

二、Web 容器关键 API 对齐

1. 拦截网页 URL 与注入 JS

网页跳转时要先拦截 JSBridge 特制 URL 串,判断当前是请求获取数据,还是返回应答数据。Android 侧修改 WebViewClient 组件的 shouldOverrideUrlLoading 方法;HarmonyOS 侧修改 Web 组件的 onLoadIntercept 接口。网页加载完成后,还要把 JSBridge 通信所需 JS 代码注入 H5。Android 侧对应 WebViewClient 组件的 onPageFinished 方法;HarmonyOS 侧对应 Web 组件的 onPageEnd 接口。

注入 JS 的方式也不同:Android 可调用 WebView 组件的 loadUrl("javascript:***") 方法或 evaluateJavaScript 方法;HarmonyOS 应调用 WebviewController 控制器的 runJavaScript 接口或 runJavaScriptExt 接口。

2. 注入 JS 对象

APP 与 H5 双向通信,本质上是互相调用对方定义的方法。但 APP 与 H5 属于不同端侧,方法不能直接被对方调用,因此要先把方法名作为对象注入,再由对方间接调用。Android 侧注入对象调用 WebView 组件的 addJavascriptInterface 方法;HarmonyOS 侧调用 Web 组件的 javaScriptProxy 接口或 WebviewController 控制器的 registerJavaScriptProxy 接口。

这里有一个关键限制:Web 组件的 javaScriptProxy 接口只能在初始化 Web 组件时调用一次,无法注入多个对象。因此实际改造采用 WebviewController 控制器的 registerJavaScriptProxy 接口,以便注入多个对象。也可以不使用对象注入,改为调用 WebviewController 控制器的 runJavaScriptExt 接口,参数输入 "javascript:window.H5方法名",同样能实现 APP 调用 H5 方法的功能。

三、工具库替换

JSBridge 涉及的工具库也要逐项迁移:JSON 串解析方面,把 Android 侧谷歌提供的三方库 Gson 改为鸿蒙系统自带的 JSON 库;URL 串解码方面,把 Android 侧的 URLDecoder 工具改为鸿蒙系统自带的 decodeURIComponent 接口;资源目录文件解析方面,把 Android 侧的 AssetManager 管理器改为鸿蒙系统自带的 ResourceManager 管理器;字符串替换方面,Android 侧 replaceAll 方法可输入字符串形式的正则串,而鸿蒙 replaceAll 方法要输入 RegExp 类型的正则串。

四、ArkTS 语法适配:闭包函数

Android APP 传统采用 Java,鸿蒙 APP 主要采用 ArkTS。两种语言在匿名函数、闭包函数等场景下写法不同,需要针对性适配。

Java 语言对于匿名函数的接口定义可以写成:
  1. public interface CallBackFunction {
  2.     public void onCallBack(String data);
  3. }
复制代码

调用时可以写匿名内部类:
  1. CallBackFunction func = new CallBackFunction() {
  2.     @Override
  3.     public void onCallBack(String data) {
  4.         ***
  5.     }
  6. };
复制代码

也可以采用 Lambda 写法:
  1. CallBackFunction func = data -> {
  2.     ***
  3. };
复制代码

ArkTS 对应的闭包函数及其接口定义必须写成:
  1. export interface CallBackFunction {
  2.     onCallBack: (data: string) => void
  3. }
复制代码

然后按下面代码调用闭包函数:
  1. let func = {
  2.     onCallBack: (data: string): void => {
  3.         ***
  4.     }
  5. };
复制代码

这种写法一开始可能觉得有些怪异,但适应后即可正常使用。

五、组件继承限制:用组合模式封装 Web

Android APP 可以自定义新组件继承自 WebView,但鸿蒙 APP 的 Web 组件属于 ArkUI,它基于 struct 定义,不支持面向对象意义上的类继承,因此无法直接继承 Web 组件。只能通过组合模式封装 Web 组件:在自定义组件的 build 函数中内嵌 Web 组件,内部管理 WebviewController,并通过回调将控制器暴露给父组件,从而实现功能扩展。

需要注意的是,组合模式传递的 WebviewController 与父组件的 WebviewController 持有不同的对象引用,不能直接调用控制器的各种方法,还要另外定义扩展的动作类型,让新类型在回调函数中使用:
  1. export type ExtendAction = (action: string) => void
复制代码

组合后的新 Web 组件要按如下方式输入动作类型变量:
  1. BridgeWeb({
  2.     src: this.localUrl,
  3.     bridge: this.bridge,
  4.     onRegister: (action: ExtendAction): void => {
  5.         this.extendAction = action
  6.     }
  7. })
  8. .width('100%').height('100%')
复制代码

六、改造结果与源码位置

改造后的 JSBridge 支持鸿蒙 APP,改造前的 JSBridge 支持 Android APP。只要使用同样的 H5 页面,即可同时对接 Android APP 和鸿蒙 APP,实现“一套网页多处运行”。

改造前后的 JSBridge 及其使用范例均已开放源码。Android 版 JSBridge 基于 com.github.lzyzsd.jsbridge 的 1.0.4 版本,模块入口为 gitee.com/aqi00/android3/tree/main/jsbridge,使用范例页面代码为 gitee.com/aqi00/android3/blob/main/chapter13/src/main/java/com/example/chapter13/WebBridgeActivity.java。鸿蒙版 JSBridge 由 1.0.4 的 Android JSBridge 改造而来,模块入口为 gitee.com/aqi00/harmony/tree/main/chapter12/jsbridge,使用范例页面代码为 gitee.com/aqi00/harmony/blob/main/chapter12/entry/src/main/ets/pages/WebBridgePage.ets,相关代码附在《鸿蒙HarmonyOS 6应用开发:从零基础到App上线》的随书源码中。

查找鸿蒙仓库尚未发现兼容 com.github.lzyzsd.jsbridge 的合适三方库,本文改造后的鸿蒙版 JSBridge 正好填补了这一空白。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-9-12 13:15 , Processed in 0.018841 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部