Flutter 鸿蒙插件适配实战:用 network_status_bridge 0.0.5 查询并监听默认网络

适配仓库: https://atomgit.com/oh-flutter/network_status_bridge

适配分支: feat/ohos_network_status_bridge_0.0.5

受测提交: 3650e53a67afe9720c03b429177c2967e0a77b19

一、最终效果与适配目标

network_status_bridge 提供一个很小但实用的接口:读取当前默认网络类型,并在默认网络变化时发出事件。上游 0.0.5 没有 OHOS 平台目录。本次适配不改变 NetworkType、getCurrentType() 和 onNetworkChanged,只为原 MethodChannel/EventChannel 接入 HarmonyOS NetConnection。

图 1:CHZ-AL00 / HarmonyOS 7.0.0.105 上订阅网络流后收到首值,当前默认网络为 Wi-Fi。

图 2:取消订阅后页面显示"监听已暂停",已接收事件数保持为 1。

图 3:重新订阅后收到新的 Wi-Fi 首值,事件数由 1 变为 2。

验证点 实测结果 证据
当前默认网络 getCurrentType() 返回 NetworkType.wifi 图 1、图 8
订阅首值 注册完成后立即查询并投递 Wi-Fi 图 1
取消和重订阅 取消后不再投递,重订阅获得新首值 图 2、图 3
自动化与构建 8 Dart + 3 Widget + 15 ArkTS,共 26 项及 HAP 通过 图 6、图 7
验证边界 未主动切换 Wi-Fi、蜂窝和离线;网络类型不等于互联网可达 图 8

二、成果速览

项目 内容
上游基线 0.0.5,提交 ba6a3fb395f29ca5a783dd283d3bafd8bcab5fd3,MIT
适配分支 feat/ohos_network_status_bridge_0.0.5
适配提交 3650e53a67afe9720c03b429177c2967e0a77b19
新增 OHOS 能力 默认网络查询、首值事件、变化去重、取消和解绑清理
原有接口 NetworkStatusBridge.getCurrentType、onNetworkChanged
权限 ohos.permission.GET_NETWORK_INFO
真机结论 Wi-Fi 查询、首值、取消与重订阅通过;真实网络切换未覆盖

2026 年 9 月 11 日,我核对 pub.dev 最新版本、上游 HEAD、候选清单以及 oh-flutter、CPF-Flutter、hxa-flutter 的同名仓库,未发现可直接使用的 OHOS 适配,因此以最新 0.0.5 开始实现。

三、实测环境

组件 实测版本
Flutter OH 3.41.10-ohos-1.0.1
Dart 3.11.5
DevEco Studio 26.0.0 Release
HarmonyOS SDK API 26;示例兼容 API 18
真机 CHZ-AL00,HarmonyOS 7.0.0.105
插件 network_status_bridge 0.0.5

环境搭建参考 Flutter OH 环境搭建指南。Flutter OH 的版本号最大标签 3.44.9+ohos-0.0.1-canary1 是预览版;本文实测的是稳定版 3.41.10-ohos-1.0.1。

四、同步仓库并补全 OHOS 结构

我保留上游 Git 历史与 MIT 许可证,将代码同步到 AtomGit,再从 0.0.5 基线创建适配分支:

shell 复制代码
git clone https://atomgit.com/oh-flutter/network_status_bridge.git
cd network_status_bridge
git switch -c feat/ohos_network_status_bridge_0.0.5 ba6a3fb395f29ca5a783dd283d3bafd8bcab5fd3
flutter create --template=plugin --platforms=ohos --no-pub .

随后将模板类替换为 NetworkStatusBridgePlugin,保留根目录 lib/ 的真实通道名,并增加独立 OHOS 示例、权限和测试。

图 4:AtomGit origin、统一适配分支、当前 HEAD 和工作区状态。

五、原有 API 与类型映射

Dart 层契约很明确:

dart 复制代码
final NetworkType current = await NetworkStatusBridge.getCurrentType();
final StreamSubscription<NetworkType> subscription =
    NetworkStatusBridge.onNetworkChanged.listen((NetworkType type) {
  debugPrint('default network: ${type.name}');
});

原生返回整数,Dart 按枚举下标映射:0 为 none、1 为 wifi、2 为 cellular、3 为 wired、4 为 other。越界值也降级成 other,防止新平台类型导致数组异常。方法通道是 network_status_bridge/method,事件通道是 network_status_bridge/event,OHOS 端必须逐字保持一致。

六、用 NetConnection 查询和监听默认网络

方法 getCurrentType 通过 hasDefaultNetSync()、getDefaultNetSync() 和 getNetCapabilitiesSync() 读取当前默认网络。实现按 Wi-Fi、蜂窝、以太网和其他类型映射;没有默认网络或无效 netId 返回 0。

监听端使用无 specifier 的 createNetConnection(),对应系统默认网络。注册成功后立即调用 emit(),因此新订阅会得到首值。netAvailable、netLost、netUnavailable 和 netCapabilitiesChange 到达时都重新查询当前默认网络,而不是直接根据回调名称猜状态。这能处理旧网络丢失与新网络成为默认值几乎同时发生的情况。

typescript 复制代码
const changed = (): void => this.emit(session);
session.monitor.on('netAvailable', changed);
session.monitor.on('netLost', changed);
session.monitor.on('netUnavailable', changed);
session.monitor.on('netCapabilitiesChange', changed);

每个 Subscription 保存最后一个类型,相同值不重复发送。取消时清空当前 session 和 sink;如果取消发生在异步注册完成之前,晚到的注册回调会立即注销旧 monitor,不能串入下一次订阅。系统查询失败通过 network_query_failed 或 network_observation_failed 上抛,不伪造成 none。

图 5:默认网络查询、事件重查、去重和订阅生命周期的生产代码。

ohos/src/main/module.json5 只增加实际需要的权限:

json5 复制代码
"requestPermissions": [
  { "name": "ohos.permission.GET_NETWORK_INFO" }
]

这个库不主动发起网络请求,因此不需要为插件本身声明 INTERNET。

七、测试、构建与交付

适配分支新增 OHOS HAR、示例宿主、双语说明、Dart/Widget 契约测试和 ArkTS 生产源码测试。签名文件、SDK 路径、依赖缓存和 HAP 构建产物不进入仓库。

shell 复制代码
flutter pub get
flutter analyze
flutter test
node --test ohos/test/network_status_bridge.test.cjs
cd example
flutter analyze
flutter test
flutter build hap --debug --no-codesign

8 项 Dart、3 项 Widget、15 项 ArkTS 共 26 项通过。测试覆盖五类映射、越界值、查询失败、首值、去重、注册失败、取消早于注册、旧回调隔离、注销失败和 Engine 重绑。

图 6:静态检查无问题,26 项自动化功能测试通过。

图 7:无签名 HAP 的实际元数据、摘要和受测提交。

八、通过固定 SHA 做真机验证

当前尚无 OHOS TAG,业务项目应锁定完整提交:

yaml 复制代码
dependencies:
  network_status_bridge:
    git:
      url: https://atomgit.com/oh-flutter/network_status_bridge.git
      ref: 3650e53a67afe9720c03b429177c2967e0a77b19

隔离宿主最初使用本地 path 对受测源码构建、签名和安装;提交前只清理了行尾空格,没有功能变化。真机读取当前默认网络为 Wi-Fi,订阅得到 Wi-Fi 首值,取消后重新订阅再次得到 Wi-Fi,三项检查全部通过。后续文章补图又复现了 1 -> 1 -> 2 的事件数变化。

图 8:真机成功项和未覆盖的外部网络切换边界。

本轮没有关闭 Wi-Fi、插拔蜂窝网络或制造真实离线,因此不能从两次 Wi-Fi 首值推断变化事件在所有系统场景都已验收。更重要的是,网络接口存在只说明可以尝试请求,不代表互联网或目标服务一定可达。

应用内补拍:手动刷新

图 9:手动刷新后页面仍读取到 Wi-Fi,并保留当前监听状态和首值事件记录。

九、FAQ

Q1:为什么 netLost 不能直接发送 none

  • 现象: 旧默认网络丢失时,新默认网络可能已经可用。
  • 原因: 回调描述的是某条网络变化,不一定代表设备此刻没有默认网络。
  • 解决方法: 每次回调重新查询默认网络并按最新 capabilities 映射。
  • 验证结果: ArkTS 测试覆盖"旧网络丢失时新网络已成为默认"的场景。

Q2:为什么刚订阅就收到一条事件

  • 现象: 用户没有切换网络,事件计数已经是 1。
  • 原因: 上游契约要求订阅注册成功后发送当前首值,便于页面立即得到状态。
  • 解决方法: 把第一条视为状态快照;如只关心变化,可在业务层保存基线后比较。
  • 验证结果: 真机两次订阅都收到 Wi-Fi 首值,行为一致。

Q3:Wi-Fi 是否说明互联网正常

  • 现象: 插件返回 wifi,业务请求仍可能失败。
  • 原因: 本库只读取默认网络承载类型,不探测 DNS、网关或服务端。
  • 解决方法: 业务请求仍需超时、重试和错误处理;需要可达性时单独做目标服务探测。
  • 验证结果: 本文明确未做外部互联网可达性验收。

十、总结

network_status_bridge 0.0.5 的 OHOS 适配保留原有两个 Dart 入口,用 NetConnection 补齐默认网络查询和变化流,并重点处理了首值、去重、晚到注册和解绑清理。26 项自动化、HAP 构建以及 Wi-Fi 查询、取消和重订阅真机验证已经通过。

当前结论不覆盖真实 Wi-Fi/蜂窝/离线切换、VPN 和其他设备。正式使用时锁定受测 SHA,并把"网络类型"和"服务可达"当成两层不同信号。

十一、参考链接

欢迎加入CPF-Flutter 鸿蒙社区:https://atomgit.com/CPF-Flutter

相关推荐
特立独行的猫A9 小时前
10 MB 的桌面 AI 客户端:用仓颉 + 系统 WebView 替代 Electron
前端·harmonyos
好的佩奇11 小时前
Dart 之模式
android·flutter·dart
阿文和她的Key11 小时前
PHP2Shell事故四层拆解:AI找洞是小时级,披露协调还是邮件级
网络·人工智能·架构·php
QZ1665609515912 小时前
数据库监测的主动防御:实时感知,看见即掌控
网络·安全·网络安全
淡淡的香烟13 小时前
Flutter实现多语言切换
android·flutter·1024程序员节
SZYSK13 小时前
鸿蒙人脸识别算法放在终端里:和外挂授权 SDK 差在排障路径
物联网·算法·华为·harmonyos
贾伟康13 小时前
【健康菜谱助手|06】HarmonyOS ArkTS 烹饪计时器实战:处理倒计时、暂停、恢复和到期反馈
软件测试·移动开发·harmonyos·arkts·arkui
北京中科新远科技14 小时前
高速接口兼容排查实战:OSFP、QSFP112与QSFP56如何逐层验证
linux·运维·网络
Lzg_na15 小时前
HDLC 协议详解
网络
今天背单词了吗98015 小时前
AI 网关:大模型时代的统一接入与安全防线
网络·人工智能·安全·ai·1024程序员节