HarmonyOS ArkWeb 开发完整指南(上篇):Hybrid 应用鸿蒙化与 JSBridge

背景

Hybrid 应用开发是介于 Web 应用和系统应用两者之间的应用开发技术,兼具"系统应用良好交互体验"的优势和"Web 应用跨平台开发"的优势。

其主要原理是由 Native 通过 JSBridge 通道提供统一的 API,然后用 Html/CSS 实现界面,JS 来写业务逻辑,能够调用系统 API,最终的页面在 WebView 中显示。

这篇文章聊聊 ArkWeb 开发的几个核心话题:

  1. Hybrid 应用鸿蒙化方案(架构设计、JSBridge、API 鸿蒙化、组件鸿蒙化)
  2. 同层渲染 Web(原理、实现、生命周期)
  3. 基于 Web 的视频适配
  4. 网页跨域解决方案
  5. Web 组件拦截能力

本文是上篇,主要介绍 Hybrid 应用鸿蒙化方案、双端通信(JSBridge)和 API 鸿蒙化。下篇将介绍组件鸿蒙化(同层渲染)、视频适配、跨域解决方案和 Web 组件拦截能力。


Hybrid 应用鸿蒙化方案

整体架构

Hybrid 应用鸿蒙化方案的整体架构包含三个核心部分:

Ark 进程

  • 由 ArkTS 引擎提供运行时,具备调用系统 API 的能力
  • 应用启动从 Ark 进程进入,完成 EntryAbility 的初始化并创建 HarmonyOS 应用页面
  • Ark 进程可以动态或者静态创建 Webview 运行时环境,并加载 html/css/js 资源文件

Webview 进程

  • 默认支持标准 W3C API,对 ArkTS 侧资源的访问有限制
  • Webview 渲染能力主要由 Web 组件提供
  • 用户可以通过 Web 组件的属性配置是否开启同层渲染能力、是否允许执行 JavaScript 脚本等

JSBridge

  • 上述两种进程的通讯机制,允许数据双向流动
  • Webview 进程通过 JSBridge 通道访问拓展 API

方案设计

Hybrid 应用鸿蒙化方案主要集中在三个方面:

  1. 双端通信 JSBridge 实现:前端与 ArkTS 进行双向通信的桥梁
  2. 拓展接口实现:针对 JS 侧平台相关的 API,提供一套 HarmonyOS 版本的实现
  3. 基于同层渲染的原生组件实现:使用系统提供的同层渲染能力,把部分性能要求比较高的前端组件改成 ArkTS 实现

业务实现中的关键点

Hybrid 应用鸿蒙化方案主要围绕双端通信、API 鸿蒙化、组件鸿蒙化三方面进行开发:

  • 双端通信:JS 侧使用 ArkTS 的通道,是鸿蒙化的基石
  • API 鸿蒙化:针对 JS 侧平台相关的 API,提供一套 HarmonyOS 版本的实现
  • 组件鸿蒙化:针对 Web 组件,以同层渲染的方式提供替代组件,以提升组件的性能与交互体验

双端通信(JSBridge)

JSBridge 扮演 Webview 进程与 ArkUI 主进程沟通的桥梁,是一种双向通信的机制。

HarmonyOS 系统提供 Web 组件以及@ohos.web.webview 等 ArkWeb API 来进行 Web 开发。可以通过 WebMessagePort 以及 javaScriptProxy 代理的方式实现 JSBridge。

WebMessagePort

WebMessagePort 是一种比较基础的消息发送以及接收机制,支持的消息类型为 string 和 ArrayBuffer。

具体业务消息内容的封装和解析需要从零设计,存在上手难、工作量大的特点。

JavaScriptProxy 代理

JavaScriptProxy 代理机制注入 ArkUI 主进程对象(如命名为 native)到 Webview 中,在 Webview 的 window 上生成对应代理对象,业务可以直接调用该代理对象的方法,相关的操作将作用到 ArkUI 主进程的 native 对象。

代码实例如下:

Web({ src:this.param.path, controller:this.webController }).zoomAccess(false).width(Const.WEB_CONSTANT_WIDTH).aspectRatio(1).margin({ left: Const.WEB_CONSTANT_MARGIN_LEFT, right: Const.WEB_CONSTANT_MARGIN_RIGHT, top: Const.WEB_CONSTANT_MARGIN_TOP}).onErrorReceive((event)=>{if(event?.error.getErrorInfo()==='ERR_INTERNET_DISCONNECTED'){this.getUIContext().getPromptAction().showToast({ message:$r('app.string.internet_err'), duration: Const.WEB_CONSTANT_DURATION});}if(event?.error.getErrorInfo()==='ERR_CONNECTION_TIMED_OUT'){this.getUIContext().getPromptAction().showToast({ message:$r('app.string.internet_err'), duration: Const.WEB_CONSTANT_DURATION});}}).onProgressChange((event)=>{if(event?.newProgress === Const.WEB_CONSTANT_PROGRESS_MAX){this.isLoading =false;clearInterval(this.intervalLoading);this.intervalLoading =-1;}}).javaScriptProxy({ object:this.linkObj, name:'linkObj', methodList:['messageFromHtml'], controller:this.webController })

前端可以使用 native.makePhoneCall(…) 的方式进行调用。且方法的参数支持基本类型、字典对象、函数等,对于 JSBridge 的设计提供了便利。

通过对比,javaScriptProxy 注入对象的方式构造 JSBridge 是一个比较好的技术选型。

JSBridge 分层设计

建议 JSBridge 的实现基于注入机制进行设计,并考虑分层设计来提高其通用性和灵活性:

通信层

  • 对上层屏蔽具体的通信机制,主要负责 Web 侧和 ArkTS 侧数据的传递
  • 但不解析数据的业务含义,不关注传递的数据内容
  • 数据可以序列化为字符串进行传递或者以 object 对象进行传递

通道层(Channel)

  • 允许注册多种方法层通道
  • 该层的 JS 侧实现负责把方法层的 API 信息对象(包含名称、参数、返回值类型等信息)打包成通信层识别的信息数据,交给通信层传递到 ArkTS 侧
  • ArkTS 侧的实现包含两个主要功能:
    • 把信息数据解包出 API 的信息,并交给 ArkTS 侧的方法层调用具体的 API
    • 执行 jsCall,ArkTS 侧通过 WebviewController.runJavaScript() 方法在执行 JS 侧的回调函数

在 JS 侧,nativeCall() 方法提供打包转换能力:

functionopenDialog(){ linkObj.messageFromHtml(prizesArr[prizesPosition]);}

在 ArkTS 侧,通过 runJavaScript() 执行 JS 侧方法:

Button($r('app.string.btnValue')).fontSize(Const.WEB_CONSTANT_BUTTON_FONT_SIZE).fontColor($r('app.color.start_window_background')).margin({ top: Const.WEB_CONSTANT_BUTTON_MARGIN_TOP}).width(Const.WEB_CONSTANT_BUTTON_WIDTH).height(Const.WEB_CONSTANT_BUTTON_HEIGHT).backgroundColor($r('app.color.blue')).borderRadius(Const.WEB_CONSTANT_BUTTON_BORDER_RADIUS).onClick(()=>{this.webController.runJavaScript('startDraw()');})

方法层(MethodChannel)

  • 可以针对一类 API 格式封装成一种 MethodChannel
  • 同种 MethodChannel 的 API 具备一致的参数规范、返回值规范,比如小程序 API 规范
  • 这样便于把 API 的调用信息封装成结构化的信息对象,供给通道层进行传递

JSBridge 的设计是否合理关系到应用的性能,开发者也可以考虑是否需要批量缓存请求再统一发送请求来减少请求次数,或者把不变的请求结果进行缓存等等。


API 鸿蒙化

H5 业务设计中除了使用 W3C API 外,还可以使用 ArkTS 侧 API 拓展来访问设备。

系统高阶 API 是对系统 API 的一层封装,实现更符合业务要求的接口。

拓展 API 的规范设计具有较大的灵活性,建议对 API 的参数,返回值类型格式进行限制,使用基本类型或者简单的字典对象,尽量避免使用复杂的类型的参数或返回值。

可以参考比较成熟的小程序框架,其规范格式可以分成三种类型:

  1. func(paramObj):其中 paramObj 包含基本类型的数据属性以及 success/fail/complete() 回调函数
  2. on/offFunc(callback):注册和移除监听函数
  3. getXxManager(): obj:获取某类功能的全局单例管理器,如文件管理器。管理器的方法也遵守上述两点规范

设计过程中可以把 API 都汇聚到一个对象作为属性字段存在,方便在切面视角增加统一的参数、返回值加工处理,拦截处理。


上篇总结

上篇介绍了 Hybrid 应用鸿蒙化方案和双端通信:

Hybrid 应用鸿蒙化方案

  • 整体架构(Ark 进程、Webview 进程、JSBridge)
  • 方案设计(双端通信、拓展接口、同层渲染)
  • 业务实现关键点(双端通信、API 鸿蒙化、组件鸿蒙化)

双端通信(JSBridge)

  • WebMessagePort(基础消息机制)
  • JavaScriptProxy 代理(注入对象方式)
  • JSBridge 分层设计(通信层、通道层、方法层)

API 鸿蒙化

  • 系统高阶 API 封装
  • 三种规范格式(func/on-offFunc/getXxManager)

下篇预告:组件鸿蒙化(同层渲染)、基于 Web 的视频适配、网页跨域解决方案、Web 组件拦截能力。

Read more

AMD Whisper 实战:如何优化大规模语音转文本的推理效率

快速体验 在开始今天关于 AMD Whisper 实战:如何优化大规模语音转文本的推理效率 的探讨之前,我想先分享一个最近让我觉得很有意思的全栈技术挑战。 我们常说 AI 是未来,但作为开发者,如何将大模型(LLM)真正落地为一个低延迟、可交互的实时系统,而不仅仅是调个 API? 这里有一个非常硬核的动手实验:基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。 从0到1构建生产级别应用,脱离Demo,点击打开 从0打造个人豆包实时通话AI动手实验 AMD Whisper 实战:如何优化大规模语音转文本的推理效率 背景痛点分析 Whisper 作为当前最先进的语音识别模型之一,在实际生产环境中面临三个核心性能瓶颈: 1. 显存占用过高:

RTX 4090 加速国产 AIGC 视频生成:腾讯混元与阿里千问开源模型

RTX 4090 加速国产 AIGC 视频生成:腾讯混元与阿里千问开源模型

国产AIGC视频大模型正加速落地,RTX 4090凭借强大算力与大显存,成为本地部署腾讯混元、阿里通义万相等前沿视频生成模型的最佳选择,开启桌面级AI创作新时代。 目录 * 一、引言:国产AIGC视频大模型,桌面算力的新疆域 * 二、解锁潜能:RTX 4090与国产视频大模型的协同优势 * 三、项目解析:国产AIGC视频模型的创新之路 * 四、部署与环境搭建:国产模型的本地化实践 * 4.1 基础环境准备 * 4.2 模型部署流程:腾讯混元与阿里通义万相的本地化实战 * 4.3 ComfyUI 集成与优化 * 五、性能测试与对比:RTX 4090 的硬核实力 * 5.1 生成速度实测 (fps / s/frame) * 5.2 显存消耗与优化策略 * 六、实际应用场景:国产模型赋能创意工作流 * 七、

昇腾NPU运行Llama模型全攻略:环境搭建、性能测试、问题解决一网打尽

昇腾NPU运行Llama模型全攻略:环境搭建、性能测试、问题解决一网打尽

背景 最近几年,AI 大模型火得一塌糊涂,特别是像 Llama 这样的开源模型,几乎成了每个技术团队都在讨论的热点。不过,这些"巨无霸"模型虽然能力超强,但对硬件的要求也高得吓人。这时候,华为的昇腾 NPU 就派上用场了。 说实话,昇腾 NPU 在 AI 计算这块确实有两把刷子。它专门为神经网络计算设计,不仅算力强劲,功耗控制得也不错,最关键的是灵活性很好,可以根据不同场景进行裁剪。所以,用它来跑大模型推理,理论上应该是个不错的选择。 为什么偏偏选了 Llama 来测试? 说到 Llama,这玩意儿现在可是开源界的"网红"。Meta 把它完全开源出来,社区生态搞得风生水起,各种优化和适配层出不穷。 其实选择 Llama 做测试,主要有这么几个考虑:

Ascend Whisper 高效部署实战:从模型优化到生产环境避坑指南

快速体验 在开始今天关于 Ascend Whisper 高效部署实战:从模型优化到生产环境避坑指南 的探讨之前,我想先分享一个最近让我觉得很有意思的全栈技术挑战。 我们常说 AI 是未来,但作为开发者,如何将大模型(LLM)真正落地为一个低延迟、可交互的实时系统,而不仅仅是调个 API? 这里有一个非常硬核的动手实验:基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。 从0到1构建生产级别应用,脱离Demo,点击打开 从0打造个人豆包实时通话AI动手实验 Ascend Whisper 高效部署实战:从模型优化到生产环境避坑指南 背景痛点分析 语音识别模型在昇腾硬件上的部署常常面临几个关键挑战: * 计算图优化不足:原生PyTorch模型直接转换后,存在大量冗余计算节点,影响NPU执行效率