Flutter 鸿蒙供应链审计实战:让高危依赖卡在 CI 门口

三套锁文件怎么一次读完、离线快照和 OSV 在线情报怎么选、退出码怎么把高危依赖卡在 CI——这篇文章用一个纯 Dart CLI 加一块 Flutter Dashboard,把这三个问题一次讲透。

仓库地址:https://atomgit.com/lqjmac/flutter_dependency_audit
版本地址:https://atomgit.com/CPF-Flutter/flutter_flutter/tree/oh-3.41.9-release
三方库框架:https://atomgit.com/oh-Flutter

0. 环境与实测设备

项版本/型号
DevEco Studio26.0.0.851(HarmonyOS SDK 7.0.0 / API 26,SDK 26.0.0.105)
Flutter3.41.9
flutter_dependency_audit1.0.0(本仓库,path 依赖)
Node.js20.19.5(仅供 ohpm / hvigor 使用)
情报源默认离线快照(4 条真实 GHSA);--online 走 OSV 在线查询
测试11 项单测:三套锁文件解析、JSON5 边界、semver 预发布段、SBOM、JSON 往返、Dashboard 渲染
实测环境HUAWEI ALN-AL00,HarmonyOS 7.0.0.109(SP6C00E105R4P3)

1. 依赖装了什么,你知道吗?——这个问题是怎么找上我的

起因其实很简单。接手一个 Flutter 鸿蒙工程做安全自查,我打开 pubspec.yaml 扫了一遍——^ 区间看着都挺新,主流包、版本也不算老,心里给了个"无风险"的结论。直到有人问我一句:pubspec.yaml 里写的是你想要的版本,那实际装进包里的呢?

我翻开 pubspec.lock 才意识到自己想简单了:真正进包的版本由锁文件决定,^ 区间只是愿望。而这还只是第一层——鸿蒙工程通常同时存在三套依赖:Dart 侧的 pubspec.lock、HarmonyOS 侧的 oh-package-lock.json5(ohpm 甚至没有 npm audit 这样的现成命令)、RN 工具链带来的 package-lock.json(传递依赖几百个,人工看不过来)。任何一个盲区都可能藏着高危漏洞。

所以这个题目的边界其实很清楚:做一个只读锁文件的供应链审计工具,不联网装包、不访问私有 registry,具体拆成三件事:

  • 三套锁文件怎么一次读完(三种格式、一个 JSON5 子集、统一模型,这是核心);
  • 漏洞情报怎么拿(默认离线快照,--online 才走 OSV,且绝不伪造数据);
  • 结果怎么卡住 CI(退出码)并把 SBOM 随制品归档。

下面是干完之后的完整记录,包括我踩的每一个坑。

2. 效果展示

按老规矩,先给效果再讲原理。示例应用叫"依赖审计"(supply_audit_example · Flutter / HarmonyOS),页面上有一行说明先把诚实的底交了:演练样本 archive 3.3.0 / dio 4.0.0 / http 0.13.0 均为真实旧版本,漏洞编号来自 GHSA——不是编造的演示数据,是 OSV 上可查的真实记录。

第一页是概览。顶部结论卡一点不含糊:

在这里插入图片描述

红色"未通过:存在高危漏洞或策略问题",下面四个大数字——4 依赖、4 漏洞、3 高危、1 中危;再往下是情报源(离线快照)、直接依赖数(3 个)、策略问题(0 条)、生态分布(Pub 4 个 · 3 命中)。最底部是审计信息(情报源 / 工程路径 test/fixtures/legacy / 生成时间)和一条复现命令——页面上展示的每一个结论,都能用 dart run lib/cli/supply_audit.dart 在命令行原样复现。审计工具不能只给结论不给证据,这条是我给自己定的规矩。

第二页是漏洞与策略。四条命中逐条列出:

在这里插入图片描述

archive@3.3.0 高危——“Archive 路径穿越:构造的 tar 条目可写出目标目录”,GHSA-9v85-q87q-g4vg,修复版本 3.3.8;同一包的另一条高危"文件名伪造:解压时可覆盖同名文件",GHSA-r285-q736-9v95;dio@4.0.0 高危——“HTTP method 未过滤 CRLF,可注入请求头”,GHSA-9324-jv53-9cc8,修复 5.0.0。每条都带编号、生态和修复版本,开发拿到手就知道该升到哪。

第三页是 SBOM:

在这里插入图片描述

说明写着它的用途——随制品归档,用于追溯"这个 HAP 到底装了哪些包"。格式 CycloneDX 1.5,组件数 4,首个 purl pkg:pub/archive@3.3.0,下面是组件清单。这一页的意义在于:报告是给人看的,SBOM 是给机器存的——半年后出一条新漏洞,拿 purl 对一遍就知道手头的 HAP 有没有中招。

3. 审计到底从哪来:锁文件、情报、退出码

写代码之前得先把原理捋好。

整条链路是"读、查、判、出"四步:

工程根目录
  ├─ pubspec.lock           ── PubspecLockParser ────┐
  ├─ oh-package-lock.json5  ── OhPackageLockParser ───┤→ Dependency(统一模型 + purl)
  └─ package-lock.json      ── NpmLockParser ─────────┘
                        │
        情报源:离线快照(4 条真实 GHSA)/ --online 走 OSV querybatch
                        │
              affects():semver 区间匹配(含预发布段)
                        │
        AuditReport:findings + 策略问题 + 退出码建议
             ├─ Markdown / JSON 报告(--format md / json)
             └─ CycloneDX 1.5 SBOM(--format sbom)

为什么只读锁文件? pubspec.yaml 是愿望,锁文件是事实;审计的事实必须来自 lockfile。而且这里有一个刻意的安全设计——审计工具自己不联网、不装包。如果审计器要先 pub get / npm install 才能干活,等于让安全工具亲手执行了一遍供应链里最危险的环节,攻击面反而被扩大了。

为什么不伪造数据? 离线快照只收录 OSV 上可查的真实 GHSA(id、受影响区间、修复版本一字不差),演示样本用的 archive@3.3.0 / dio@4.0.0 / http@0.13.0 也都是真实存在过漏洞的旧版本。安全工具编一条"演示漏洞",用户第一次对不上 OSV 就会永远失去信任。

为什么是退出码? 报告再漂亮,CI 不看;CI 只认进程退出码。--fail-on high 命中即退出码 2,一行 shell 就能把高危依赖卡在合并门口——这比任何"安全周报"都有效。

顺手记一笔性能账:整条链路是纯 Dart 读三个文本文件、内存里匹配一个 4 条的快照数组——秒级完成,CI 里几乎无感;只有 --online 才需要网络(OSV 的 querybatch 批量接口 + 漏洞详情,失败自动回退离线快照)。换句话说,瓶颈不在工具,在你想让情报多新鲜。

各条路线对照一下:

方案覆盖生态鸿蒙工程适用性
dart pub outdated仅 Dart看不到 ohpm / npm 两套依赖
npm audit仅 npm看不到 pub / ohpm 两套依赖
ohpm 官方工具—没有内置 audit 类命令
商业 SCA 平台全依赖账号、网络与接入成本,CI 卡点重
本库 CLI + Dashboardpub + ohpm + npm一次读完三套锁文件,离线可跑,退出码卡 CI

能力边界也要说清楚:它解决的是"锁文件级别的快检 + SBOM",不做深度代码扫描,替代不了专业 SCA 平台;离线快照目前只收录 Pub 生态的 4 条 GHSA,覆盖面有限,认真审计请开 --online;不处理 git/path 依赖的漏洞匹配,但会把它们单独标记为可复现性问题。了解了这个边界,你就知道什么时候用它卡 CI,什么时候送专业平台深扫。

4. 工程怎么搭:一个纯 Dart 内核,两副面孔

先看整体结构。这个库有意思的地方在于同一份内核服务两个入口:命令行给 CI,Dashboard 给人:

flutter_dependency_audit/
├─ lib/
│  ├─ audit.dart                       # 纯 Dart 入口(CLI 用,不依赖 Flutter)
│  ├─ flutter_dependency_audit.dart    # Flutter 入口(导出 Dashboard)
│  ├─ cli/supply_audit.dart            # CLI:参数解析 + 退出码
│  └─ src/
│     ├─ models.dart                   # Dependency / Advisory / Finding / AuditReport
│     ├─ auditor.dart                  # 编排:解析 → 匹配 → 策略 → SBOM
│     ├─ osv_client.dart               # OSV querybatch + 漏洞详情
│     ├─ advisory_snapshot.dart        # 离线快照(4 条真实 GHSA)
│     ├─ sbom.dart                     # CycloneDX 1.5
│     ├─ markdown_report.dart
│     ├─ parsers/                      # pub / ohpm / npm 三套锁文件解析
│     │  └─ json5_lite.dart            # JSON5 归一化(单遍状态机)
│     └─ widgets/audit_dashboard.dart  # 审计 Dashboard(三 Tab)
├─ ohos/                               # 只读 HAR:暴露 apiVersion / deviceType
├─ example/                            # Flutter OHOS 示例(Dashboard 宿主)
├─ test/                               # 11 项单测 + 演练锁文件 fixtures/legacy
└─ docs/

在这里插入图片描述

这次设计最关键的决定有三个:

编排拆到"每一步都能单测"。 Auditor 只做流水线:读锁文件 → 匹配漏洞 → 策略检查 → 生成 SBOM,解析器、情报源、SBOM 生成器全是独立单元。类注释把动机写得很直白:“网络只发生在 OsvClient,不污染其它逻辑”——所以离线单测不需要网,在线逻辑坏了好定位。

CLI 和 Dashboard 共用同一份模型。 AuditReport.fromJson / toJson 手写序列化,单测覆盖 JSON 往返——CLI 写出的 report.json,Dashboard 原样读回渲染。命令行与世界另一端的图形界面说的是同一句话,页面上那条"复现命令"才真的可复现。

鸿蒙侧只做只读环境标注。 ohos/ 是一个极小的 HAR(AuditRuntimePlugin),只暴露 apiVersion / deviceType 用于报告头部标注运行环境——不申请权限、不联网。审计工具的原生层越薄,它自己成为供应链风险的概率越低。

对使用方来说,两个入口长这样。CI 里一条命令:

dart run lib/cli/supply_audit.dart \
  --root . \
  --format md \
  --out build/security/audit.md \
  --fail-on high

App 里一个 Widget(不依赖路由与状态管理,可直接嵌"设置 → 安全中心"):

final report = AuditReport.fromJson(
  jsonDecode(await rootBundle.loadString('assets/report.json'))
      as Map<String, Object?>,
);

AuditDashboard(
  report: report,       // 当前工程
  demoReport: demo,     // 可选:演练样本
  projectLabel: 'my_app',
);

下面把内核拆开讲:三套锁文件、一个 JSON5 子集、两种情报源、一个 semver 细节、三样产物。

5. 把代码讲透

5.1 三套锁文件,一个模型

Auditor.auditDirectory 的编排朴素到近乎直白——存在哪个锁文件就读哪个,各自进解析器,产出统一的 Dependency:

// lib/src/auditor.dart - auditDirectory()(节选)
final pubLock = File('${root.path}${Platform.pathSeparator}pubspec.lock');
if (await pubLock.exists()) {
  files.add('pubspec.lock');
  dependencies.addAll(
      const PubspecLockParser().parse(await pubLock.readAsString()));
}

final ohLock = File('${root.path}${Platform.pathSeparator}oh-package-lock.json5');
if (await ohLock.exists()) {
  dependencies.addAll(const OhPackageLockParser().parse(
    await ohLock.readAsString(),
    directNames: ohpmNames,        // 直接依赖判定来自宿主声明
  ));
}
// package-lock.json 同理……

if (files.isEmpty) {
  throw StateError('未找到 pubspec.lock / oh-package-lock.json5 / '
      'package-lock.json,请先在工程根目录完成依赖安装');
}

三个值得单独说的地方:"直接依赖"是审计的关键属性——pubspec.lock 天然区分直接/传递,但 oh-package-lock.json5 里全是扁平的锁定条目,ohpm 侧的直接依赖只能从宿主声明反推(directNames 参数就是干这个的),概览页"直接依赖 3 个"的数字由此而来;模型统一带 purl(pkg:pub/archive@3.3.0 这种格式),它是漏洞匹配和 SBOM 的公共主键;一个锁文件都没有时明确报错而不是输出空报告——审计工具最忌讳"成功生成了 0 条结论"。

5.2 JSON5 归一化:一个单遍状态机

oh-package-lock.json5 是 JSON5——带注释、尾逗号、无引号 key。第一反应是正则替换:把注释删了、把 ,\s*[}\]] 删了,再丢给 jsonDecode。json5_lite.dart 的文档注释里专门把这条路判了死刑:

/// 实现是一遍逐字符扫描:注释、字符串、无引号 key、尾逗号都在同一次扫描里
/// 处理,不对整段文本做正则替换。这点很关键——对全文跑 `,\s*[}\]]` 会把
/// 字符串里的 `,}` 当成尾逗号删掉,属于"看起来跑通了、其实悄悄改了数据"。
String normalizeJson5(String input) { /* 单遍逐字符扫描 */ }

锁文件里全是包描述和路径字符串,"desc": "a,} b" 这种内容随时出现——正则替换会把它悄悄改成 "a b",解析"成功",数据已脏。正确做法是逐字符扫描,遇到字符串整体读出重写成合法 JSON 字符串,注释只在字符串外丢弃。这个子集刻意不追求完整 JSON5(不处理 +1、.5、0x1F),遇到不认识的语法让 jsonDecode 直接抛错——宁可报错,不要静默解析出半个锁文件。

5.3 情报源:离线快照与 OSV 在线

两条路,一条默认:

离线快照(advisory_snapshot.dart)是编译进包里的常量数组——4 条真实 GHSA,数据注明来自 OSV 在 2026-11-11 的公开记录,每条保留 id、受影响区间、修复版本和原文链接。CI 无网也能跑,审计结果可复现(同一份快照永远得到同一份报告)。

在线模式(osv_client.dart)走 OSV 的 querybatch 批量接口一次查全部依赖,命中的漏洞 id 再分块并发拉 /v1/vulns/ 详情(Future.wait 按块等待)。网络只活在这个类里;--online 查询失败时回退离线快照——降级不降诚实,报告头部的"情报源"字段会如实标注这一轮用的是 osv 还是 offline。

5.4 semver 区间:预发布段的坑

漏洞匹配的核心是"我装的版本落在受影响区间里吗",这里藏着一个容易被忽略的规则:

/// 预发布版按 semver 规则小于同版本正式版——`3.3.8-dev < 3.3.8`;
/// 否则"修复版本是 3.3.8、实际装的是 3.3.8-dev"会被漏报。
return _comparePrerelease(left.prerelease, right.prerelease);

如果字符串比较或忽略预发布段,3.3.8-dev 会被当成"已经到了 3.3.8、漏洞已修复"——但它恰恰是还没进正式修复版的版本,必须报。区间匹配是审计工具的裁判,裁判错一次,后面全是错的;这条规则配了专门的单测。

5.5 三样产物:报告、SBOM、退出码

审计跑完输出三样东西。Markdown/JSON 报告给人看,--format 二选一;CycloneDX 1.5 SBOM 给机器存,每个组件带 bom-ref 和 purl,随制品归档;退出码给 CI——--fail-on 取 none/low/medium/high/critical,命中即退出码 2。示例页面把三样都演了:结论卡和复现命令在"概览",逐条漏洞在"漏洞与策略",SBOM 摘要在第三个 Tab。

Dashboard(audit_dashboard.dart,约 830 行)是报告的可视化形态:三个分段 Tab(概览 / 漏洞与策略 / SBOM)、分组卡片、系统蓝——CHANGELOG 里专门写了一条"视觉改为 HarmonyOS 设计语言:去掉渐变与重阴影,正文 16fp"。它不依赖路由和状态管理,AuditDashboard(report: ...) 一行嵌入——审计结果不该藏在 CI 日志里,让每个开发在 App 里都能看到,才有日常的敬畏。

6. 我踩过的坑(每一条都有真实报错)

这一节可能是全文最值钱的部分。以下坑全部来自这次开发的真实排查记录。

坑一:只看 pubspec.yaml 就下结论。 本文的开头故事,也是最容易犯的错——^ 区间干净不等于锁文件干净,真实版本在 pubspec.lock 里。教训:审计的事实来源只能是锁文件,愿望清单不是证据。

坑二:JSON5 用正则预清洗,数据悄悄变脏。 对全文跑 ,\s*[}\]] 删尾逗号,看起来一次跑通,实际会把字符串里的 ,} 一起删掉——锁文件内容被静默篡改,后面的漏洞匹配全在脏数据上跑。修复:单遍逐字符状态机(见 5.2)。教训:预处理的正则要审一遍"字符串里会怎样"。

坑三:semver 预发布段漏报。 “修复版本 3.3.8,装的 3.3.8-dev” 被区间匹配判成已修复——按 semver 规则预发布版小于正式版,必须继续报。修复:版本比较显式处理预发布段(3.3.8-dev < 3.3.8)并配单测。裁判错一次,满盘皆错。

坑四:ohpm 的"直接依赖"没法从锁文件看出来。 oh-package-lock.json5 是扁平的锁定条目,没有 pub 侧的直接/传递分层。修复:从宿主声明反推直接依赖集合(directNames),概览页"直接依赖 3 个"才有了准确口径。

坑五:工程路径含中文,hvigor 直接报 Invalid project path。 示例构建时踩的——目录名里有中文,hvigor 不认。修复无他:构建副本放纯英文路径(Windows 上建议 D:\build\...)。鸿蒙工具链对路径的容忍度要按最低标准预估。

坑六:审计工具自己成了供应链风险。 最初设计让 CLI 自动执行 pub get 再审计,写了一半反应过来:让安全工具亲手执行依赖安装,等于扩大了它要防护的攻击面。修复:只读锁文件,缺锁文件就报错让用户先装(见 5.1 的 StateError)。

坑七:伪造演示数据的诱惑。 最省事的演示是编几条假漏洞,想多吓人有多吓人。修复:演练样本用真实旧版本(archive 3.3.0 / dio 4.0.0 / http 0.13.0)配 OSV 可查的真实 GHSA 编号,页面顶部明示"漏洞编号来自 GHSA"。安全工具的公信力只有一次,别在演示里花掉它。

7. 现在怎么用:从一条命令到 CI 卡点

经过上面的整理,这个工程是"CLI + 库 + Dashboard"三合一(包名 flutter_dependency_audit,版本 1.0.0,Apache-2.0)。作为 path 依赖接入:

dependencies:
  flutter_dependency_audit:
    path: ../flutter_dependency_audit

CI 里一条命令卡高危(命中退出码 2,流水线直接失败):

dart run lib/cli/supply_audit.dart \
  --root . \
  --format md \
  --out build/security/audit.md \
  --fail-on high

常用参数:--root(工程根目录)、--format md/json/sbom、--out(输出路径)、--online(OSV 在线情报,默认离线快照)、--deny(禁用依赖名,可重复)、--fail-on(none/low/medium/high/critical)。

App 里展示审计结果,两行代码嵌 Dashboard(见第 4 节);示例应用的报告资产由 example/assets/report.json 与 demo_report.json 提供,重新生成:

dart run lib/cli/supply_audit.dart --root example \
  --format json --out example/assets/report.json --fail-on none
dart run lib/cli/supply_audit.dart --root test/fixtures/legacy \
  --format json --out example/assets/demo_report.json --fail-on none

当前版本在 Flutter 3.41.9(oh-3.41.9-release)/ DevEco Studio 26.0.0.851 / HarmonyOS SDK API 26 环境下验证:flutter test 11 项单测与 flutter analyze 全绿——覆盖三套锁文件解析、JSON5 注释与尾逗号边界、semver 预发布段、4 条真实 GHSA 区间匹配、SBOM purl、JSON 往返与 Dashboard 渲染;示例应用在 HarmonyOS 模拟器(ohos-x64)运行,演练样本审计 4 依赖 4 漏洞(3 高危 1 中危)结论"未通过",CLI 命令与页面展示逐字一致,SBOM 随 HAP 归档可回溯。锁文件级别的快检 + SBOM + 退出码,三件事都落了地——剩下的深度扫描,交给专业平台就好。

相关推荐

RN 鸿蒙安全三方库落地:react-native-digital-shield,密钥不出 TEE,AES-GCM/RSA-JWT 跨端身份打通

本文基于 RNOH 0.84 与 HarmonyOS API 26,自研数字盾库 react-native-digital-shield,把 ArkTS 专属的 HUKS、asset 能力经TurboModule 桥接给 JS:提供 AES-256-GCM 加解密与密钥托管、敏感资产存储、RSA-2048 签发校验 RS256 JWT,并以 JWK 公钥和 HS256 共享密钥实现跨端身份互认,密钥明文始终不出 TEE。文中还复盘 TurboModule 双侧注册、GCM 需拆分 16 字节

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 16

Flutter 修复鸿蒙 WebView Cookie 同名键丢失:离线回读与开发助手复核实录

修复了 Flutter 三方库 webview_cookie_manager 鸿蒙端因同名键误判导致的 Cookie 名称丢失问题,确保业务键如 path、domain 等在回读时正确保留。修复后,模拟器与真机测试均实现四组数据完整恢复,值中多等号也保持不变。补丁已提交至 CPF-Flutter 官方仓库,提升插件在鸿蒙平台的可靠性。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 26

Flutter 鸿蒙启动图撤销后编译失败:用 DevEco Code 复核三方库修复

本文针对 Flutter 鸿蒙启动图撤销时导致编译失败的问题,修复了 flutter_native_splash_ohos 库在移除启动图时误删仍被引用资源的缺陷。通过保留1×1透明图片并透传自定义模块路径,确保资源引用完整性,使工程可正常构建。修复已提交至官方仓库,支持幂等操作与多场景验证,提升开发体验。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 40

Flutter 接入鸿蒙 ArkWeb 预初始化:帮助页首开时机与主线程成本实测

为解决Flutter鸿蒙版webview_flutter无法在无视图状态下提前初始化引擎的问题,我在其原生实现中新增可选静态入口initializeWebEngine()。实测表明,在2秒预热窗口下,页面首屏渲染(FCP)耗时从中位数1791ms降至1019ms,显著提升首次打开体验;而在零延迟场景下,总路径耗时略有上升,需权衡预热时机与用户等待成本。该补丁已提交至CPF-Flutter官方仓库,支持社区协作优化。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 36

Flutter 优化鸿蒙 printing_ohos 多页 PDF 光栅化:原生资源释放与缓冲复用

针对鸿蒙端 printing_ohos 插件存在的页码映射错误与高内存占用问题,本文提出并实现三项优化:修正页码索引映射、引入原生资源分层释放机制、复用像素缓冲区。修复后,第三页显示正确,内存增长显著降低——在模拟器上PSS增量中位数下降65.8%,真机测试下降64.4%。完整补丁已提交至官方仓库,支持社区协作与问题反馈。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 33

React Native 鸿蒙权限审计实战:让每一项权限都有人认领

本文介绍一款纯 JS 编写的 React Native 鸿蒙权限审计工具,解决权限声明与使用对账难、最小权限集计算矛盾、审核必填字段缺失三大痛点。通过 module.json5 声明、使用台账与源码扫描三路输入对账,自动识别未使用权限、补全 reason/usedScene、生成可粘贴的最小清单,并支持 CI 卡控与风险分评估。工具内核独立,离线运行,兼顾准确性与安全性,助力应用高效通过审核。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 12

Cordova 鸿蒙 WebView 安全实战:能改的运行时拦,改不了的构建期审

本文通过 cordova-plugin-harmony-webguard 插件,解决 Cordova/HarmonyOS 应用中导航安全、引擎不可修改配置、JS 门面静默降级三大难题。基于运行时策略闸门(onPageStart + JS 预检)与构建期审计 CLI(扫描 MainPage.ets、config.xml 等),实现协议拦截、白名单校验、高危配置阻断,支持 CI 失败退出,将安全基线可视化、可测化,真正落地“能改的运行时拦,改不了的构建期审”。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 25

React Native 鸿蒙端侧 OCR 实战:TurboModule 与纯 TS 引擎的逐字契约

本文以鸿蒙真机上的 React Native 0.84 工程为例,详解三大难题:通过 TurboModule 接入 HarmonyOS Core Vision Kit 实现端侧离线 OCR;规避 Metro 预置头导致的 require 不存在问题;实现 npm 包与 HAR 双形态交付。项目采用 codegen 生成 ArkTS 接口,结合纯 TS 回退引擎,确保跨引擎逐字符一致,并通过 autolinking 支持无缝集成。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 90

Flutter 鸿蒙端侧 OCR 实战:让文字识别留在设备上

本文通过一个运行在鸿蒙真机上的 Flutter 插件工程,系统解决了三大核心问题:如何统一内存、文件、相册三类输入的识别链路;如何实现与 KMP 版本的 JSON 契约逐字节对齐;以及在系统不提供置信度时如何诚实处理。基于 HarmonyOS Core Vision Kit,插件实现端侧离线 OCR,全程无网络、无权限、无密钥,支持真实小票与截图识别,性能稳定(312~507ms),并通过 35 项单元测试与真机集成验证。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 148

跨端 RN 鸿蒙碰一碰分享库实战:基于 Share Kit 封装 react-native-ohos-knock-share,实现卡片、文件一碰传

本文介绍基于React Native的鸿蒙碰一碰分享库,解决RN开发者在鸿蒙生态中无法便捷使用Share Kit碰一碰功能的痛点。通过封装NFC/星闪触碰、3秒发送窗口、沙箱文件URI转换等核心逻辑,实现跨设备快速传递链接、文件、图片等内容。支持手机、平板、PC多端适配,提供回环演示与真机实测验证,显著降低接入门槛,提升跨端协作效率。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 180

React Native 鸿蒙实战:给应用接入小艺语音指令,跑通 Skill 声明到操作闭环

本文介绍如何在 React Native 鸿蒙(RNOH)工程中实现小艺技能闭环,通过开源库 react-native-ohos-ai-agent 封装技能声明、语音指令接收、端侧执行与结果回传全流程。针对三方应用权限限制,精准定位可操作边界,实现“被唤起→执行→反馈”链路贯通。结合五张真机截图验证:技能注册、指令匹配、意图上报、智能体调起及对话层弹出等关键节点均成功,完整打通语音交互闭环,助力应用无需入口即可被用户“叫”到。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 169

Flutter 鸿蒙实现精准碰一碰分享:tap_share_ohos 三方库打通真机传文件与传卡片

本文针对Flutter在鸿蒙系统上“碰一碰”分享功能缺失的痛点,基于DevEco Studio 26.0、HarmonyOS 7.0 API 26与Flutter 3.41.9实测环境,提出并实现开源库tap_share_ohos。该库封装NFC、Share Kit、权限管理及分布式能力,通过Dart门面层统一接口,利用MethodChannel与BasicMessageChannel对接原生ArkTS逻辑,实现文件与卡片的碰一碰分享。真机测试显示,可无缝调起系统分享面板,支持华为分享接力

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 169

Flutter 鸿蒙实战:用三方库接入小艺语音指令与智能体,跑通 Skill 声明到操作闭环

本文基于 flutter_ohos_ai_agent 三方库,实现 Flutter 应用一键调起鸿蒙小艺智能体。针对跨端框架对接鸿蒙 AI 能力的碎片化、环境差异等痛点,通过插件封装系统 Kit 能力,提供统一 Dart API。实测显示,模拟器与真机均支持文本/语音指令闭环,真机可完整调起小艺面板并回传事件。核心原理为:利用 ArkUI 承载页桥接 FunctionComponent,通过 MethodChannel 与 EventChannel 实现 Flutter 与原生能力双向通信,完成从语音识别到

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 151

RNOH 原生内存泄漏定位与治理:借助 LeakyGuard 实现图片解码降采样、LRU 字节缓存、资源生命周期管控,长列表图片页面峰值内存优化

本文面向 RNOH 0.84 长列表图片场景,剖析滑动数分钟后进程被系统杀掉的根因:原图解码尺寸失控、缓存按条数限流、PixelMap未显式 release。基于自研LeakyGuar,TurboModule 库,给出 desiredSize 真降采样、字节预算 LRU 缓存(逐出必 release)、资源登记与快照 diff、卸载即释放 Hook 的闭环方案,实测单图内存降 98.6%,24 图峰值由 1098.6MB 降至15.8MB。并总结双侧注册、ArkTS 语法差异、vp 转像

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 245

Flutter 鸿蒙空间音频实战:让音乐播放器的声音“长出方位感“

本文通过一个真实运行的 Flutter 工程,系统解析了在鸿蒙系统上实现空间音频的三大核心问题:基于双耳时间差(ITD)、声级差(ILD)和频谱整形的方位感算法;耳机切换与音频焦点管理;以及播放器与音效的集成。项目使用自研插件 spatial_audio,结合原生 HarmonyOS 接口,实现了跨设备的空间音频体验,支持普通耳机,无需硬件依赖,并提供实时参数反馈与系统状态监听。附带完整代码仓库与实测效果展示,为 Flutter on HarmonyOS 的音频开发提供了可复用的技术方案。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 289

Flutter 鸿蒙 HiTrace 请求归因:图片压缩等待时,主线程在做什么

为定位鸿蒙平台图片压缩性能瓶颈,我在 flutter_native_image 插件中新增可选的 HiTrace 阶段追踪功能,支持按请求开启解码、缩放、编码与资源释放阶段的耗时分析。通过对比模拟器与真机(华为畅享 100 Pro Max)数据,精准识别出耗时主要集中在解码与编码阶段,显著提升诊断效率。相关代码已提交至官方仓库,助力开发者快速定位性能问题。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 1万+

Flutter 适配鸿蒙折叠屏铰链角度按需订阅:支架调节页用完即停与重入实测

本文介绍对 Flutter 三方库 dual_screen 的优化:针对支架调节页等短时观察场景,保留原有缓存入口的同时,新增按需订阅机制。通过按需启停监听,实现页面退出后停止原生回调,避免无效数据更新。实测显示,无消费者时原生回调从3条降至0条,重进页面则等待新事件,更符合临时工具页的使用逻辑。完整代码已开源,支持鸿蒙折叠屏角度动态感知,适用于需精准控制生命周期的折叠屏应用开发。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 1万+

Flutter 适配鸿蒙手表屏幕形状:让计时卡片按圆屏和方屏布局

本文基于 wear_plus 1.2.4 版本,为鸿蒙系统补全屏幕形状查询功能,使 WatchShape 能正确返回 round 等形状信息。通过在原 Dart 接口不变的前提下,新增鸿蒙平台处理器,实现与 Android 一致的异步查询逻辑。对照实验验证:适配后页面可从“查询未接入”变为“圆屏已确认”,日志成功接收系统回执,布局行为保持一致。完整代码开源至 oh-flutter/wear_plus,支持 Flutter 鸿蒙穿戴设备开发。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 1万+

Flutter 优化鸿蒙剪贴板大图复制卡顿:从主线程同步阻塞到异步文件描述符直解

针对鸿蒙系统下 flutter_image_clipboard 插件复制高清图片时阻塞主线程的问题,本文提出三项优化:异步文件描述符直解、异步剪贴板写入及原生资源逆序释放。实测显示,模拟器事件循环最大间隔从300.32ms降至54.36ms(降幅81.9%),真机上更从133.20ms降至11.20ms(降幅91.59%),显著提升页面响应性。完整代码已开源,支持直接使用与社区交流。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 1万+

Flutter 三方库 petalmaps_ohos 的 OpenHarmony 适配实战(0 → 1 全记录)

本文详细记录了从零构建 Flutter 三方库 petalmaps_ohos 并适配 OpenHarmony/HarmonyOS 平台的全过程,涵盖项目初始化、原生实现(基于 ArkTS 和 MethodCallHandler)、插件注册、功能验证及升级至 HarmonyOS SDK 26 的关键步骤。重点解析了为何需实现 AbilityAware 获取 UIAbilityContext 以确保地图调起成功,并通过分层架构、枚举封装与兼容性设计,实现功能完整、易用且低维护成本的“调起系”地图插件,

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 59

Flutter 三方库 holding 的 OpenHarmony 适配实战:从 0 到 1 开发一个鸿蒙感知插件

本文详述了从零实现开源 Flutter 插件 holding 并适配 OpenHarmony/HarmonyOS 的全过程。基于鸿蒙专属 MultimodalAwarenessKit,实现握持手与操作手状态感知,覆盖事件流订阅、状态查询及 API 26 新增接口,确保功能一致、性能高效、接口稳定。通过 Dart 层封装、ArkTS 原生桥接、真机验证与单元测试,完成插件工程化落地,并发布至 pub.dev,为同类系统能力插件的鸿蒙化提供可复用的技术路径。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 28

Flutter 三方库 gesturesshare 从 0 到 1:鸿蒙隔空传送分享插件的开发、升级与发布实战

本文详述了 Flutter for OpenHarmony 三方库 gesturesshare 从零开发到发布全过程:基于 HarmonyOS 隔空传送能力,实现跨设备图片与 App Linking 一键分享。涵盖双端代码设计、API 26 升级、真机验证及 Pub 发布流程,提供 Dart/ArkTS 对照与踩坑复盘。项目填补 Flutter 生态空白,推动鸿蒙多设备交互能力普及,助力开发者快速接入系统级功能。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 28

Qt 鸿蒙沉浸光感实战:让玻璃的每个像素自己发光

本文通过一个 QML 模块与 Qt for OpenHarmony 构建实践,完整解答了三个核心问题:如何用 81 行 GLSL 实现无图片依赖的动态玻璃材质(含光核漂移、视差、SDF 圆角与颗粒);如何在 Qt Quick 中通过 C++ 控制器实现弹层锚定与翻转;以及如何将 Qt 应用交叉编译并以 HAR 形式部署至鸿蒙系统。项目基于 Qt 5.12.12,利用 ShaderEffect 实现纯渲染级视觉效果,兼顾性能与跨平台兼容性,提供可复用的开源方案。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 23

开源鸿蒙平台 KMP_CMP 三方库「端侧语音转文字」适配全流程

本项目实现KMP/CMP在OpenHarmony鸿蒙平台的语音转文字(TTS)完整链路适配,通过Kotlin/Native共享模型、C ABI/N-API桥接与ArkTS交互,解决权限、音频格式、生命周期及跨平台契约等难题。支持中文、英文、日文多语言识别,提供统一结果模型与JSON序列化,实测于华为Mate 80 Pro Max模拟器,验证了JVM测试、Native动态库、HAP签名部署及真机识别全流程。项目结构清晰,分六阶段推进,确保代码复用与平台无关性,为KMP在鸿蒙生态落地提供可复用的技术范式。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 30

开源鸿蒙平台 KMP_CMP 三方库「端侧OCR」新特性适配

本项目实现Kotlin Multiplatform(KMP)在OpenHarmony平台的端侧OCR适配,基于HarmonyOS 7.0 SDK与Compose Multiplatform 1.9.2,成功打通JVM、Kotlin/Native与ArkTS间的数据交互。通过C ABI/N-API桥接层,实现KMP模型与Core Vision Kit识别结果的跨语言共享,支持中、英、日、韩四语识别。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 13

开源鸿蒙平台 KMP/CMP 三方库「智感握姿」新特性

本项目实现鸿蒙KMP/CMP平台下智感握姿能力的跨端适配,基于Kotlin Multiplatform构建共享状态模型,通过C ABI与ArkTS桥接,支持左手、右手、双手等五种握持状态的稳定传递。项目打通ohosArm64目标、Native动态库构建与DevEco Studio集成链路,提供统一API与真机验证示例,确保状态模型、事件序列与生命周期在多端一致。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 19

Electron 鸿蒙沉浸光感实战:把玻璃交给操作系统去发光

本文通过一个 Electron 库与 HarmonyOS 三方库,系统解决三大核心问题:跨平台材质路径对齐(macOS vibrancy、Windows acrylic、鸿蒙 backgroundBlurStyle)、菜单子窗口精准定位(坐标转换与工作区适配)、以及无脚本菜单文档的安全事件回传(自定义 URL scheme 与焦点管理)。基于 CPF-Electron 鸿蒙化分支,实现桌面级玻璃效果——材质由操作系统合成器采样,网页仅渲染薄色层与光斑,确保视觉一致性与性能优化。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 21

Flutter 修复 flutter_secure_storage 鸿蒙入口路由与前缀隔离:让多账号登录凭证在手机上独立读写与清理

本文针对 flutter_secure_storage 在鸿蒙平台的适配问题,修复了主包缺失 TargetPlatform.ohos 路由导致的 unsupported_platform 错误,并统一鸿蒙子包多账号前缀的读写与清理范围,解决键值覆盖、前缀错用及批量操作匹配过宽等问题。修复后,业务层可继续使用统一接口实现跨账号安全存储,保障数据隔离性。完整代码已开源至 abaoge/flutter_secure_storage。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 1万+

Cordova 鸿蒙沉浸光感实战:让弹层玻璃“喝到“背景的光

本文通过一个 HarmonyOS 模拟器上的 Cordova 项目,详解了在 WebView 中实现“玻璃拟态”效果的三大核心问题:利用 backdrop-filter 实现背景实时模糊与提亮,构建四层结构(采样、渐变底、光场、噪点)模拟真实玻璃质感;通过锚点定位与动态布局实现弹层贴边生长;并集成焦点管理、系统返回键及 inert 属性,确保交互礼仪完整。插件为纯 JS 无原生依赖,基于 ArkWeb 内核,兼顾性能与真实背景采样,适用于菜单、浮层等场景。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 28

CMP 鸿蒙透明玻璃实战:让悬浮导航栏真正透出光场

本文通过一个KMP/CMP工程,详解如何在鸿蒙上用Kotlin实现沉浸光感玻璃材质的逐像素渲染。核心解决三大问题:透明感源于环境光场与带alpha的柔光混合、玻璃“透光”依赖alpha保留的屏幕混合算法、跨平台一致性通过软件光栅器与原生桥接实现。项目以纯代码生成全屏光场与悬浮玻璃组件,无图片资源,支持动态切换调色板,实测模拟器下亚秒级重绘,完整复现官方“沉浸光感”视觉效果。仓库地址:https://atomgit.com/lqjmac/spatial-glass-cmp。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 28
上一篇: React Native 鸿蒙端侧 OCR 实战:TurboModule 与纯 TS 引擎的逐字契约
下一篇: Cordova 鸿蒙 WebView 安全实战:能改的运行时拦,改不了的构建期审
AtomGit 代码君
AtomGit 代码君 企业官方账号 企业官方账号
博客等级 码龄6年 2万+粉丝 856原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值