欢迎光临
我们一直在努力

Flutter for OpenHarmony:web 拥抱 Web 标准的桥梁(Wasm GC 与 DOM 互操作) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

请添加图片描述

前言

随着 Flutter 3.x 全面拥抱 Wasm(WebAssembly),Dart 团队推出了全新的 package:web 来取代老旧的 dart:html。 package:web 是基于最新的 JS Interop 机制构建的,它不仅性能更好,而且兼容 Wasm GC 标准。

虽然这个库通过名字看是为 “Web” 平台的,但对于 OpenHarmony 开发者来说,了解它有着特殊的意义:

  • 混合开发:鸿蒙原生支持 ArkWeb (WebView),在 Flutter 中通过 JS互操作与 Web 页面交互是常见需求。
  • 架构演进:理解 package:web 的设计有助于理解 Dart 如何与宿主环境(无论是 Browser 还是 Embedder)进行高效通信。
  • (注:本库主要用于 Flutter Web 目标平台。在鸿蒙 App 原生端,通常使用 flutter_inappwebview 或 js 库进行 JS 交互。但如果你的鸿蒙应用采用了“Flutter Web 运行在鸿蒙 WebView 中”的架构,本库就是核心)。

    一、核心原理

    package:web 不再封装很重的 Dart 对象,而是直接将 Dart 类型映射到 JS 对象(Zero-cost interop)。

    #mermaid-svg-ZFaxn7dihhnkERuq{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ZFaxn7dihhnkERuq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ZFaxn7dihhnkERuq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ZFaxn7dihhnkERuq .error-icon{fill:#552222;}#mermaid-svg-ZFaxn7dihhnkERuq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZFaxn7dihhnkERuq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ZFaxn7dihhnkERuq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZFaxn7dihhnkERuq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZFaxn7dihhnkERuq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ZFaxn7dihhnkERuq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZFaxn7dihhnkERuq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZFaxn7dihhnkERuq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZFaxn7dihhnkERuq .marker.cross{stroke:#333333;}#mermaid-svg-ZFaxn7dihhnkERuq svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZFaxn7dihhnkERuq p{margin:0;}#mermaid-svg-ZFaxn7dihhnkERuq .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ZFaxn7dihhnkERuq .cluster-label text{fill:#333;}#mermaid-svg-ZFaxn7dihhnkERuq .cluster-label span{color:#333;}#mermaid-svg-ZFaxn7dihhnkERuq .cluster-label span p{background-color:transparent;}#mermaid-svg-ZFaxn7dihhnkERuq .label text,#mermaid-svg-ZFaxn7dihhnkERuq span{fill:#333;color:#333;}#mermaid-svg-ZFaxn7dihhnkERuq .node rect,#mermaid-svg-ZFaxn7dihhnkERuq .node circle,#mermaid-svg-ZFaxn7dihhnkERuq .node ellipse,#mermaid-svg-ZFaxn7dihhnkERuq .node polygon,#mermaid-svg-ZFaxn7dihhnkERuq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ZFaxn7dihhnkERuq .rough-node .label text,#mermaid-svg-ZFaxn7dihhnkERuq .node .label text,#mermaid-svg-ZFaxn7dihhnkERuq .image-shape .label,#mermaid-svg-ZFaxn7dihhnkERuq .icon-shape .label{text-anchor:middle;}#mermaid-svg-ZFaxn7dihhnkERuq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ZFaxn7dihhnkERuq .rough-node .label,#mermaid-svg-ZFaxn7dihhnkERuq .node .label,#mermaid-svg-ZFaxn7dihhnkERuq .image-shape .label,#mermaid-svg-ZFaxn7dihhnkERuq .icon-shape .label{text-align:center;}#mermaid-svg-ZFaxn7dihhnkERuq .node.clickable{cursor:pointer;}#mermaid-svg-ZFaxn7dihhnkERuq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ZFaxn7dihhnkERuq .arrowheadPath{fill:#333333;}#mermaid-svg-ZFaxn7dihhnkERuq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ZFaxn7dihhnkERuq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ZFaxn7dihhnkERuq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZFaxn7dihhnkERuq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ZFaxn7dihhnkERuq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZFaxn7dihhnkERuq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ZFaxn7dihhnkERuq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ZFaxn7dihhnkERuq .cluster text{fill:#333;}#mermaid-svg-ZFaxn7dihhnkERuq .cluster span{color:#333;}#mermaid-svg-ZFaxn7dihhnkERuq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ZFaxn7dihhnkERuq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ZFaxn7dihhnkERuq rect.text{fill:none;stroke-width:0;}#mermaid-svg-ZFaxn7dihhnkERuq .icon-shape,#mermaid-svg-ZFaxn7dihhnkERuq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZFaxn7dihhnkERuq .icon-shape p,#mermaid-svg-ZFaxn7dihhnkERuq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ZFaxn7dihhnkERuq .icon-shape rect,#mermaid-svg-ZFaxn7dihhnkERuq .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZFaxn7dihhnkERuq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ZFaxn7dihhnkERuq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ZFaxn7dihhnkERuq :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    @JS() Annotation

    Wasm / JS

    Dart Code

    JS Interop Layer

    浏览器 DOM / JS Context

    二、OpenHarmony 适配说明

    场景一:Flutter App 编译为 HAP (原生) 此时 package:web 不可用,因为底层没有 V8/SpiderMonkey 引擎环境。你应该使用 plugin 机制与 ArkTS 通信。

    场景二:Flutter Web 运行在鸿蒙浏览器/WebView 此时 package:web 完全可用,且是官方推荐方案。你可以用它来调用鸿蒙浏览器暴露给 JS 的特殊能力。

    三、基础用例 (Web 环境)

    在这里插入图片描述

    3.1 操作 DOM (新一代 API)

    import 'package:web/web.dart' as web;

    void main() {
    // 💡 无需 dart:html,直接操作宿主 DOM
    final div = web.document.createElement('div') as web.HTMLDivElement;
    div.innerText = 'Hello from Modern Dart Web!';
    div.style.backgroundColor = 'blue';

    web.document.body?.append(div);
    }

    在这里插入图片描述

    3.2 调用 JS 函数

    // 假设 JS环境中有一个函数: function showAlert(msg) { alert(msg); }

    import 'dart:js_interop';

    ()
    external void showAlert(JSString message);

    void callJs() {
    showAlert('HarmonyOS Web'.toJS);
    }

    在这里插入图片描述

    四、完整实战示例:鸿蒙 ArkWeb 中的 JS 互操作

    本示例展示了在 Flutter Web 编译模式下,如何利用 package:web 与鸿蒙宿主环境进行高效通信。

    import 'dart:js_interop';
    import 'package:web/web.dart' as web;

    // 💡 模拟鸿蒙系统注入的全局 JS 桥接对象
    ('OhosBridge')
    extension type OhosBridge._(JSObject _) implements JSObject {
    external static JSString getDeviceId();
    external static void onActionSuccess(JSString data);
    }

    void callHarmonyOS() {
    // 1. 检查对象是否存在
    if (web.window.has('OhosBridge')) {
    // 2. 直接获取设备 ID
    final id = OhosBridge.getDeviceId().toDart;
    print('✅ 获取到鸿蒙设备 ID: $id');
    }
    }

    在这里插入图片描述

    五、总结

    package:web 是 Dart 迈向 Wasm 时代的关键一步。 虽然它主要面向 Web 平台,但在“大前端”融合的今天,鸿蒙应用中嵌入 Web 页面、小程序的情况比比皆是。掌握新一代的 JS 互操作技术,能让你在混合架构开发中游刃有余。

    赞(0)
    未经允许不得转载:171主机测评 » Flutter for OpenHarmony:web 拥抱 Web 标准的桥梁(Wasm GC 与 DOM 互操作) 深度解析与鸿蒙适配指南
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址