项目仓库: oh-flutter/flutter_rust_bridge

上游项目: flutter_rust_bridge

Rust 社区: 开放原子旋武开源社区

本文演示版本: flutter_rust_bridge 2.13.0-beta.6(codegen 与 Dart 包同版本)。其余版本流程相同,具体 API 请以你安装版本的生成结果为准。

flutter_rust_bridge(简称 FRB)是一套 Flutter/Dart 与 Rust 的绑定生成工具。开发者只需编写 Rust 函数、结构体、枚举、异步方法和 Trait,工具就能生成 Dart API、FFI 调用及数据转换代码,Flutter 侧调用体验接近普通 Dart API。

它适合把图像音视频、AI 本地推理、加密安全、复杂算法、数据库与搜索、网络协议解析及实时数据处理放到 Rust 中。Flutter 负责界面与交互,Rust 负责计算密集、底层或需要跨端复用的业务逻辑,FRB 负责两侧之间的类型和调用边界。
在这里插入图片描述

图 1:flutter_rust_bridge 官方项目 Logo,图片来源于上游仓库。


一、SDK 简介与适用场景

FRB 的目标不是替应用重新设计 Rust API,而是识别已有的自然 Rust 代码,并生成跨语言胶水。同步函数可以生成普通 Dart 调用,async fn 可以生成 Future,结构化类型可以转换成 Dart 模型,流式结果可以通过 StreamSink 推送到 Dart Stream

很多 Flutter 项目在早期会把所有逻辑都写在 Dart 中,等到功能变复杂后才发现某些库只存在于 Rust 生态,或者某段计算在移动设备和桌面设备上都占用了太多时间。重新手写一套 C 接口、Dart FFI 声明和内存释放代码,成本往往比预想的高。FRB 把这部分重复劳动交给生成器,开发者把精力放在 Rust API 的边界和业务规则上。

FRB 不是运行时远程服务,也不是把 Rust 编译成 Web API。生成器读取 Rust 源码,产生 Dart 侧绑定和底层调用代码;应用构建时再把 Rust 编译为目标平台的 native library。这样调用仍然发生在本地进程中,适合对延迟、离线能力或数据隐私有要求的场景。

在这里插入图片描述

图 2:官方仓库展示的 FRB 能力概览,具体能力仍应以使用的版本和配置为准。

常见分工如下:

组成主要职责适合放置的内容
Flutter/Dart页面、交互、状态展示和路由表单、列表、动画、用户操作
Rust高性能计算、文件、数据库、协议和安全逻辑编解码、推理、搜索、加密、长耗时任务
FRB生成绑定、参数转换、错误和异步结果传递Dart API、FFI 入口、结构体/枚举/Stream 映射

二、环境准备(15 步新手流程)

参考文章:Flutter 鸿蒙环境搭建可对照官方文档 flutter-oh-env-setup.mdHarmonyOS 适配实践:Flutter 项目全流程指南-环境搭建;Rust 环境搭建可对照 Rust 入门:环境搭建并跑出第一行代码

这一节把环境搭建拆成 15 个可验证的步骤。总原则是:每一步都先执行一条检查命令,看到预期输出后再进下一步。这样哪一层出了问题,立刻能定位到是哪一步没搭好,而不是在最后一起排查。

15 步总览如下,后续小节按这个顺序展开:

步骤做什么验证命令通过标准
1安装 DevEco Studio打开 IDE能正常启动,自带 SDK/ohpm/hvigor/node
2准备 OpenHarmony SDK见 IDE 内 SDK 路径sdk/ 目录存在
3获取 Flutter OH 源码flutter --version输出版本号
4配置环境变量echo $PATH / flutter doctor -v命令能找到 Flutter 与工具链
5检查 Flutter 鸿蒙环境flutter doctor -vFlutter 与 HarmonyOS toolchain 均为 [√]
6Flutter Hello Worldflutter run页面出现默认 counter 界面
7安装 Rust 工具链rustc -V cargo -V输出版本号
8Rust Hello Worldcargo run终端输出 Hello, world!
9安装 FRB codegenflutter_rust_bridge_codegen --version输出版本号
10创建 frb_hello 工程flutter pub get无报错
11运行 FRB 基础页面flutter run页面显示 flutter_rust_bridge
12修改 Rust bridge_namecargo build编译通过
13重新生成绑定flutter_rust_bridge_codegen generate生成文件更新
14页面显示 Rust 文本flutter run页面显示新文本
15运行到 OpenHarmony 真机flutter run -d <id>真机出现同一页面

先看自己电脑是什么系统。 下面步骤中 macOS / Linuxexport 写进 shell 配置文件,Windows 用「环境变量」面板配置。两者配置的变量名相同,只是写入方式不同。

2.1 步骤 1~2:安装 DevEco Studio,拿到 OpenHarmony SDK

DevEco Studio 是 OpenHarmony 官方 IDE。安装后它自带 OpenHarmony SDK、ohpm(包管理)、hvigor(构建)、node 等工具链,因此步骤 1 和 2 一起完成。

  1. 前往 华为开发者联盟 - DevEco Studio 下载,按系统下载最新版。

  2. 安装前先确认装了 JDK 17 及以上(OpenHarmony SDK 依赖 Java):

    java -version
    

    没有就先去 Oracle JDK 17 或 OpenJDK 下载安装。

  3. 解压并安装 DevEco Studio。默认路径:

    • macOS:/Applications/DevEco-Studio.app/Contents
    • Windows:如 D:\Huawei\DevEco Studio

    记下这个路径,后面配置 TOOL_HOME 会用到。它下面的 sdk/ 目录就是 OpenHarmony SDK。

模拟器限制:DevEco Studio 模拟器当前支持 macOS(arm64)Windows(x64),macOS(x86) 暂不支持。无受支持设备的读者请准备 OpenHarmony 真机;使用模拟器还需要完成实名认证的华为账号。

2.2 步骤 3:获取 Flutter OH 源码

Flutter 的普通稳定版不包含 ohos 设备支持,必须使用 Flutter OH(Flutter OpenHarmony 适配版)。推荐用 Git 克隆:

git clone https://gitcode.com/CPF-Flutter/flutter_flutter.git
cd flutter_flutter
git checkout -b dev origin/dev   # 或按版本配套表选择对应 tag

验证:

./bin/flutter --version

能输出版本号即可。若无法用 Git,也可以去 Flutter OH 仓库 下载 ZIP 解压(但后续无法 git pull 更新,建议还是用 Git)。

2.3 步骤 4:配置环境变量

把下面几条路径写进环境变量,让终端能直接找到 flutterohpmhvigorhdc 等命令。先用占位符理清每个路径:

占位符含义示例
<JAVA_HOME path>JDK 安装路径macOS:/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
<DevEco-Studio Path>DevEco Studio 安装路径macOS:/Applications/DevEco-Studio.app/Contents;Windows:D:\Huawei\DevEco Studio
<flutter_flutter path>Flutter OH 源码路径/Users/<用户名>/ohos/flutter_flutter
macOS / Linux

先确认当前 shell(echo $SHELL),输出 /bin/zsh 编辑 ~/.zshrc,输出 /bin/bash 编辑 ~/.bash_profile(Linux 一般 ~/.bashrc)。把下面内容追加进去:

# JDK 17
export JAVA_HOME=<JAVA_HOME path>
export PATH=$JAVA_HOME/bin:$PATH

# OpenHarmony SDK、ohpm、hvigor、node(TOOL_HOME 即 DevEco Studio 安装路径)
export TOOL_HOME=<DevEco-Studio Path>
export DEVECO_SDK_HOME=$TOOL_HOME/sdk
export PATH=$TOOL_HOME/tools/ohpm/bin:$PATH
export PATH=$TOOL_HOME/tools/hvigor/bin:$PATH
export PATH=$TOOL_HOME/tools/node/bin:$PATH
export HDC_HOME=$TOOL_HOME/sdk/default/openharmony/toolchains   # 可选,hdc 指令

# Flutter 及国内镜像
export PUB_CACHE=~/Pub/Cache
export PATH=<flutter_flutter path>/bin:$PATH
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
export FLUTTER_GIT_URL=https://gitcode.com/CPF-Flutter/flutter_flutter.git   # 可选

保存后执行 source ~/.zshrc(或 source ~/.bash_profile)让它立即生效。

Windows

打开「此电脑 → 属性 → 高级系统设置 → 高级 → 环境变量」,建议都加到系统变量

变量说明
JAVA_HOME<JAVA_HOME path>JDK 安装路径
Path%JAVA_HOME%\bin追加到现有值
TOOL_HOME<DevEco-Studio Path>DevEco 安装路径
DEVECO_SDK_HOME%TOOL_HOME%\sdkOpenHarmony SDK
Path%TOOL_HOME%\tools\ohpm\binohpm
Path%TOOL_HOME%\tools\hvigor\binhvigor
Path%TOOL_HOME%\tools\nodenode
Path<flutter_flutter path>\binFlutter
PUB_CACHE%USERPROFILE%\Pub\Cachepub 缓存
PUB_HOSTED_URLhttps://pub.flutter-io.cn国内镜像
FLUTTER_STORAGE_BASE_URLhttps://storage.flutter-io.cn国内镜像
FLUTTER_GIT_URLhttps://gitcode.com/CPF-Flutter/flutter_flutter.git可选

配置完重启终端/命令行窗口再继续。

2.4 步骤 5:flutter doctor 检查

逐项确认工具链:

java -version          # JDK
hdc -v                 # 设备调试工具
ohpm -v                # OpenHarmony 包管理
hvigor -v              # 构建工具
flutter doctor -v      # Flutter 与 OpenHarmony SDK 联合检查

flutter doctor -v 输出里,FlutterHarmonyOS toolchain 两项应为 [√]

若报 No Hmos SDK found,说明 Flutter 没找到 SDK 路径,执行:

flutter config --ohos-sdk "<DevEco-Studio Path>/sdk"
# Windows 示例:flutter config --ohos-sdk "D:\Huawei\DevEco Studio\sdk"
flutter config --list   # 应看到 ohos-sdk 已配置

2.5 步骤 6:Flutter Hello World(先验证 Flutter 自己通不通)

在接入 Rust 之前,先确认 Flutter OH 能独立创建并运行页面。这一步和第 15 步「运行到真机」共用一个签名/构建链路,先在这里打通:

flutter create --platforms ohos hello_ohos
cd hello_ohos
flutter build hap --debug          # 先编译,验证构建链路
flutter devices                     # 拿到 device-id
flutter run -d <device-id>          # 或 flutter run --debug -d <device-id>

<device-id>flutter devices 输出的设备 ID。首次运行会编译 Flutter 引擎并安装应用,耗时比后续长。页面出现 Flutter 默认 counter 界面,说明 Flutter、设备连接、签名和最基本的 OHOS 构建链路已经打通。

真机签名:运行到真机前需先签名。在 DevEco Studio 打开 File → Project Structure → Signing Configs,勾选 Automatically generate signature 自动生成。模拟器可跳过。

编译产物在 build/ohos/hap/ 下,默认签名包名形如 entry-default-signed.hap。也可以用 hdc -t <device-id> install <hap path> 手动安装。

2.6 步骤 7~8:安装 Rust,跑通 Rust Hello World

FRB 的生成器不会替代 Rust 编译器,Rust 工具链负责把 rust/ 目录编译成 native library。安装细节可参考 Rust 入门:环境搭建并跑出第一行代码。推荐 rustup 安装:

# macOS / Linux
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Windows:下载 rustup-init.exe 双击运行

安装后验证(V 是大写):

rustc -V
cargo -V

再跑一个独立的 Rust Hello World,确认 Rust 工具链本身没问题:

cargo new hello_rust
cd hello_rust
cargo run      # 终端输出 Hello, world!

Windows 常见坑cargo runerror: linker 'link.exe' not found,是因为 Rust 默认用 MSVC 工具链但没装 C++ 链接器。去装 Visual Studio Build Tools,勾选「使用 C++ 的桌面开发」,重启终端即可。macOS 需装 Xcode Command Line Tools(xcode-select --install),Linux 一般自带 GCC。

2.7 步骤 9:安装 FRB 代码生成器

FRB codegen 是一个 Cargo 命令行工具:

cargo install flutter_rust_bridge_codegen
flutter_rust_bridge_codegen --version

安装失败先保留完整错误日志(常见是 crates.io 访问问题,可配 Cargo 镜像);不要在项目里手工创建生成文件。codegen 版本要和项目依赖的 flutter_rust_bridge Dart 包一致,本文演示 2.13.0-beta.6

2.8 工具链检查清单

进入下一步前,逐项确认:

检查项命令通过标准
JDKjava -version17 及以上
DevEco/OpenHarmony SDKIDE 内查看 sdk/ 路径目录存在
Flutter OHflutter --version输出 OHOS 分支版本
Flutter 诊断flutter doctor -vFlutter 与 HarmonyOS toolchain 为 [√]
Flutter Hello Worldflutter runcounter 页面出现
Rustrustc -V输出版本
Cargocargo -V输出版本
Rust Hello Worldcargo run输出 Hello, world!
FRB codegenflutter_rust_bridge_codegen --version输出版本

三、FRB:从创建到 Hello Rust(步骤 10~15)

这是本文的核心部分。先用一条命令创建工程,它自带一个能显示 Rust 返回值的基础页面——这就是你问的「环境搭好之后有没有页面展示」的答案:有,而且第一次运行就能看到 Rust 函数返回的 flutter_rust_bridge

3.1 步骤 10:一条命令创建 frb_hello 工程

在单独的练习目录执行(不要在已有业务仓库根目录直接跑):

mkdir -p ~/workspace && cd ~/workspace
flutter_rust_bridge_codegen create frb_hello
cd frb_hello
flutter pub get

create 会一次性生成 Flutter 工程、Rust crate、FRB 配置和一个最小 API。生成后的目录结构如下(frb_hello 换成你的工程名):

frb_hello/
├── lib/
│   ├── main.dart                 # 基础页面:调用 Rust bridge_name 并显示
│   └── src/rust/                 # FRB 生成的 Dart 绑定(勿手改)
│       ├── frb_generated.dart
│       └── api/simple.dart
├── rust/
│   ├── Cargo.toml                # Rust 依赖与 crate 配置
│   └── src/
│       ├── lib.rs                # pub mod api; mod frb_generated;
│       └── api/
│           ├── mod.rs            # pub mod simple;
│           └── simple.rs         # 手写 Rust API:greet / init_app
├── rust_builder/                 # cargokit 胶水:让 Flutter 各平台构建 Rust
├── flutter_rust_bridge.yaml      # 生成配置
└── pubspec.yaml                  # Flutter + flutter_rust_bridge + rust_builder 依赖

三个关键文件的真实内容如下(flutter_rust_bridge.yamlgreet 取自 2.13.0-beta.6create 输出,bridge_name 和页面为本演示所用版本):

flutter_rust_bridge.yaml

rust_input: crate::api
rust_root: rust/
dart_output: lib/src/rust

rust/src/api/simple.rs(手写的 Rust API,就是待会儿要改的文件):

#[flutter_rust_bridge::frb(sync)] // Synchronous mode for simplicity of the demo
pub fn greet(name: String) -> String {
    format!("Hello, {name}!")
}

#[flutter_rust_bridge::frb(sync)]
pub fn bridge_name() -> String {
    "flutter_rust_bridge".to_string()
}

#[flutter_rust_bridge::frb(init)]
pub fn init_app() {
    // Default utilities - feel free to customize
    flutter_rust_bridge::setup_default_user_utils();
}

lib/main.dart(基础页面):

import 'package:flutter/material.dart';
import 'package:frb_hello/src/rust/api/simple.dart';
import 'package:frb_hello/src/rust/frb_generated.dart';

Future<void> main() async {
  await RustLib.init();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('flutter_rust_bridge quickstart')),
        body: Center(
          child: Text(
            bridgeName(),
            style: const TextStyle(fontSize: 24),
          ),
        ),
      ),
    );
  }
}

这个页面的关键不在布局,而在启动顺序:先 await RustLib.init() 加载并初始化 native library,再 runApp。这样页面第一次构建时,Rust 动态库已经就绪,bridgeName() 才能返回 flutter_rust_bridge

3.2 步骤 11:运行 FRB 自带基础页面

flutter devices
flutter run

先选电脑上已有的 Flutter 设备(模拟器/桌面/真机均可),页面显示:

flutter_rust_bridge quickstart          ← AppBar 标题
flutter_rust_bridge                     ← Rust 函数 bridge_name() 的返回值

看到这行 flutter_rust_bridge,说明三件事同时打通了:Flutter 页面能启动、native library 被正确加载、Dart 通过 FRB 绑定调到了 Rust 并拿到返回值。这就是 FRB 的「Hello World」,等价于 Flutter 的默认 counter 页面。

在这里插入图片描述

图 3:frb_hello 的 quickstart 页面在手机上的实际运行效果:AppBar 标题为 flutter_rust_bridge quickstart,页面中央是 Rust 函数 bridge_name() 返回的 flutter_rust_bridge,右上角 DEBUG 角标说明当前为 Flutter 调试构建。

截图怎么准备? 这一步的截图应使用你自己电脑上的实际运行结果,建议两张:

  1. 步骤 6 的 Flutter 默认 counter 页面,证明 OHOS Flutter 环境可用;
  2. 本步骤的 FRB quickstart 页面(flutter_rust_bridge),证明 Rust 函数已经过 FRB 绑定被 Dart 调用。

截图时同时保留终端里的 flutter devicesflutter run 输出,读者就能把设备 ID、AppBar 标题和页面文字对应起来。截图不要出现个人路径、签名证书、Token 或私有仓库地址。

3.3 步骤 12:修改 Rust bridge_name 函数

打开 rust/src/api/simple.rs,把 bridge_name 的返回值改成你想让页面显示的文本,例如:

#[flutter_rust_bridge::frb(sync)]
pub fn bridge_name() -> String {
    "你好,来自 Rust 的问候 🦀".to_string()
}

改动后先确认 Rust 侧能编译:

cd rust && cargo build && cd ..

3.4 步骤 13:重新生成绑定

FRB 生成代码不会因为 Rust 文件变化自动更新。改了 Rust 之后必须重新生成:

flutter_rust_bridge_codegen generate

generate 读取 flutter_rust_bridge.yaml,扫描 rust/src/api/,更新 lib/src/rust/ 下的 Dart 绑定和 C 头文件。生成完可以看一眼 lib/src/rust/api/simple.dart,它会被更新为类似:

String greet({required String name}) =>
    RustLib.instance.api.crateApiSimpleGreet(name: name);
String bridgeName() => RustLib.instance.api.crateApiSimpleBridgeName();

3.5 步骤 14:在 Flutter 页面显示 Rust 返回的文本

main.dart 里已经在调用 bridgeName(),重新生成后热重载或重新运行即可看到新文本:

flutter run

页面会显示:

flutter_rust_bridge quickstart
你好,来自 Rust 的问候 🦀

注意:改了 Rust 后必须停止并重新构建(native library 要重新编译),仅靠 Dart 热重载不能替代原生库重编译。先用 r 热重载如果没变,就 R 热重启,仍不行就停掉进程重新 flutter run

3.6 步骤 15:运行到 OpenHarmony 真机

确认 FRB 页面在桌面/模拟器上正常后,切到 OpenHarmony 真机:

flutter devices                      # 拿到 ohos 真机 device-id
flutter run -d <ohos-device-id>      # 或 flutter run --debug -d <ohos-device-id>

首次在 ohos 目标上构建会编译 Rust 为 OpenHarmony 的 native 库(rust_builder 里的 cargokit 胶水负责各平台构建,其 pubspec.yaml 已声明 ohos: ffiPlugin: true),并编译 Flutter 引擎、签名、安装 HAP,耗时较长。真机应显示与桌面一致的页面:未改 bridge_name 时是 flutter_rust_bridge,按步骤 12 改过之后就是步骤 14 里的新文本。

若只想验证构建不连设备,可以先:

flutter_rust_bridge_codegen generate
flutter analyze
flutter test
cargo test

frb_hello 还自带一个集成测试 integration_test/simple_test.dart,断言页面里出现 flutter_rust_bridge

testWidgets('Can call rust function', (WidgetTester tester) async {
  await tester.pumpWidget(const MyApp());
  expect(find.text('flutter_rust_bridge'), findsOneWidget);
});

可以跑一次确认整条调用链:

flutter test integration_test/simple_test.dart

四、Rust API 与 Dart 调用链

下面是一个最小示意 API,使用 FRB 能识别的普通 Rust 类型、结构体、枚举和异步函数:

#[derive(Debug, Clone)]
pub struct ImageSize {
    pub width: u32,
    pub height: u32,
}

pub enum ProcessMode {
    Preview,
    Export,
}

pub fn describe(size: ImageSize, mode: ProcessMode) -> String {
    let mode_text = match mode {
        ProcessMode::Preview => "preview",
        ProcessMode::Export => "export",
    };
    format!("{}x{} ({mode_text})", size.width, size.height)
}

pub async fn calculate_histogram(bytes: Vec<u8>) -> Result<Vec<u64>, String> {
    // 示例中省略具体算法;真实项目可在这里调用 Rust 图像、音视频或 AI 库。
    Ok(vec![bytes.len() as u64])
}

生成器根据配置扫描这些 API,生成 Dart 侧对应的方法和模型。应用启动时初始化 Rust 库,然后像调用普通异步 Dart API 一样使用:

Future<void> run() async {
  await RustLib.init();
  final label = describe(
    size: const ImageSize(width: 1920, height: 1080),
    mode: ProcessMode.preview,
  );
  final histogram = await calculateHistogram(bytes: imageBytes);
  debugPrint('$label: ${histogram.length}');
}

这段代码中的 RustLib.init() 只负责加载并初始化 native library。它不等于业务初始化;应用仍然可以在 Rust 中另外提供 init_app、数据库打开或模型加载函数,并由 Flutter 在合适的启动阶段调用。把库加载和业务初始化分开,遇到初始化失败时更容易定位。

如果返回值较大,例如一帧图像、音频缓冲区或搜索结果列表,需要提前决定数据是否适合一次性复制。小对象使用结构体最直观;大量字节可以使用 Uint8List 对应的类型;持续产生的数据则考虑 StreamSink。跨语言接口的设计通常比单个函数的实现更影响整体性能。

调用链可以概括为:

Flutter 页面

Dart 生成 API

FRB 生成绑定

Dart FFI

Rust 函数或 async fn


五、异步、错误与持续事件

Result<T, E> 会在生成的 Dart API 中体现为成功结果或异常路径。Rust 侧应保留明确的错误类型或错误消息,Dart 侧再决定如何展示。

对于持续输出的任务,可以让 Rust 接收 StreamSink<T>

pub async fn process_stream(
    input: Vec<u8>,
    sink: StreamSink<u32>,
) -> Result<(), String> {
    for (index, _chunk) in input.chunks(4096).enumerate() {
        sink.add(index as u32).map_err(|error| error.to_string())?;
    }
    Ok(())
}

Dart 侧通过生成的接口监听事件。实际项目应在页面退出时取消订阅,并在 Rust 中释放文件、网络连接或任务句柄。StreamSink 适合增量结果;一次性结果仍使用普通返回值或 Future

异步函数和流并不是同一件事。async fn 通常在任务完成后返回一次结果;StreamSink 可以在处理过程中多次发送进度或部分结果。图像导出可以返回一个最终文件路径,视频转码则可以持续报告已经完成的帧数。选择哪一种接口,应由页面需要观察的状态决定。

错误也要在边界处保持稳定。Rust 内部可以使用多个错误枚举和 ? 逐层传播,暴露给 Flutter 时再统一成带有错误码、消息和上下文的类型。不要在 Rust 中直接 unwrap() 处理来自文件、网络或用户输入的数据;一次未处理的 panic 会让 Dart 侧只能看到 native 调用异常。


六、本项目使用的 Rust 特性

FRB 的价值在于让这些 Rust 特性能够沿着生成的类型边界进入 Flutter:

Rust 特性在 FRB SDK 接入中的用法
struct定义图像尺寸、配置、搜索结果等结构化数据,生成 Dart 模型和字段访问。
enummatch表达处理模式、有限状态和错误分类,在 Rust 中完成穷举分支。
async/await把文件、网络、数据库和推理等异步任务暴露为 Dart Future
Result<T, E>?沿 Rust 调用链传播错误,在 Dart 边界转换为可处理的异常或失败结果。
Option<T>表达可选参数和可能缺失的返回值,避免使用特殊字符串或数字表示空值。
所有权与借用在 FFI 边界明确数据何时复制、移动或只读借用,保持 Rust 内存安全。
Trait 与 Trait object抽象不同算法、存储或服务实现;FRB v2 支持将部分 Trait 能力映射为 Dart 可用接口。具体可用写法需按生成器版本验证。
泛型与迭代器在 Rust 内部复用集合处理和算法逻辑,跨语言边界使用生成器支持的具体类型。
Drop/RAII让文件、锁、网络资源在作用域结束时自动释放,减少页面退出后的资源泄漏。
StreamSink<T>将 Rust 的增量处理结果映射为 Dart Stream<T>,适合进度、日志和实时数据。

这些特性并不要求全部出现在同一个函数中。常见的工程做法是用结构体描述请求和结果,用枚举表达状态,用 Result 处理错误,用 async/await 承载 IO,再用 StreamSink 把长任务的中间结果传回 Flutter。Trait 和泛型更多用于 Rust 内部的可替换实现,只有确实需要跨语言调用时才把它们放到 FRB API 边界。


七、生成绑定与接入步骤

在工程根目录执行生成命令:

cargo install flutter_rust_bridge_codegen
flutter_rust_bridge_codegen generate
flutter pub get

官方仓库也提供一条命令创建新工程:

cargo install flutter_rust_bridge_codegen
flutter_rust_bridge_codegen create my_app
cd my_app
flutter run

生成文件属于构建产物的一部分,修改 Rust API 后应重新执行 generate,再重新构建应用。不要手工修改生成的 Dart 或 C 头文件;需要改变接口时回到 Rust API 和配置文件。

在 CI 中可以把生成步骤作为接口检查:先执行 generate,再执行 git diff --exit-code,这样 Rust API 改动却忘记提交生成文件时会立即失败。对于本地开发,建议在修改函数签名、字段名称或枚举分支后立刻生成,编译器会尽早提示 Dart 侧需要同步的调用点。


八、验证与常见问题

建议分别验证 Rust、生成器和 Flutter 页面:

cargo test
flutter_rust_bridge_codegen generate
flutter analyze
flutter test

测试至少覆盖结构体和枚举转换、异步成功与失败、空输入、长耗时任务取消、Stream 结束和页面销毁。若部署到 OpenHarmony,再按应用工程的签名、设备连接和 HAP 构建流程进行真机验证;本文没有把 SDK 仓库中的单元测试写成某个鸿蒙设备已经通过的证明。

常见问题包括:生成器找不到配置文件、rust_input 路径错误、Dart 与 Rust 类型不匹配、修改 Rust 后没有重新生成、原生库未重新编译,以及远程 Git 依赖仍锁定旧提交。排查时先看生成命令的完整日志,再检查 flutter_rust_bridge.yamlpubspec.lock 和 Rust 编译目标。

如果问题只在某个平台出现,还要把平台因素单独列出来:Rust target 是否安装,native library 是否被打包,应用架构是否与设备一致,OpenHarmony 工程是否正确引用生成的产物。先在 dart_minimal 一类小工程验证绑定,再回到完整业务项目,通常比直接在大型工程里反复改配置更快。


九、FAQ:从问题定位到 Issue

9.1 FRB 生成失败先检查什么?

确认当前目录存在 flutter_rust_bridge.yaml,并核对 rust_inputrust_rootdart_output 是否指向实际路径。然后确认 codegen、Dart 包和 Rust crate 的版本来自同一套项目说明。

9.2 为什么修改 Rust 后 Flutter 没有变化?

FRB 生成代码不会因 Rust 文件变化自动更新。重新执行 flutter_rust_bridge_codegen generate,再停止并重建应用;仅依靠 Dart 热重载不能替代原生库重编译。

9.3 Trait 或复杂类型不能生成怎么办?

先把问题缩小到一个最小 Rust 文件,确认目标版本支持的 Trait、生命周期、泛型和 opaque 类型范围。将 Rust 版本、配置文件、平台、完整错误和最小代码一并提交到 FRB Issues 或对应 AtomGit 仓库。

9.4 OpenHarmony 上安装成功但调用失败怎么办?

检查应用是否使用了最新生成绑定和对应的 native 库,确认 Flutter OH 工具链、Rust target、签名包和设备架构一致,再查看应用日志。FRB 只负责绑定生成,平台构建和设备权限仍由宿主应用负责。

9.5 为什么接口改名后出现大量 Dart 编译错误?

Rust 的公开函数名、参数名、字段名和枚举分支都会影响生成 API。接口改名后先重新生成,再让编译器列出所有调用点;不要为了暂时通过编译而同时保留两套含义相同的接口。需要兼容旧版本时,可以在 Rust 侧保留一个明确的转发函数,并在文档中标出迁移方式。

9.6 怎样判断问题应该反馈给 FRB 还是业务仓库?

能在最小 Rust 函数和最小 Flutter 工程中复现的代码生成、类型转换或 Stream 问题,适合提交到 FRB;只有在完整应用中出现的权限、签名、数据库、网络和页面生命周期问题,应先在业务仓库处理。反馈时附上版本、平台、配置文件、最小代码和完整日志,维护者才能复现。


后续扩展与项目入口

接入 FRB 后,可以在同一套 Dart API 下逐步增加本地图像处理、音视频管线、AI 推理、加密模块、全文搜索和协议解析。建议先确定跨语言数据模型,再决定哪些任务需要异步、流式输出或取消,最后用生成器保持 Dart 与 Rust 接口同步。

项目入口:AtomGit flutter_rust_bridge。示例中的业务算法、设备截图和 OpenHarmony 真机结果需要在具体应用工程中补充验证后再作为项目实测内容发布。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐