flutter-interoperating-with-native-apis
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseIntegrating Platform-Specific Code in Flutter
在Flutter中集成平台专属代码
Contents
目录
Core Concepts & Terminology
核心概念与术语
- FFI (Foreign Function Interface): The library used to bind Dart directly to native C/C++ APIs.
dart:ffi - Platform Channel: The asynchronous message-passing system (,
MethodChannel) connecting the Dart client (UI) to the host platform (Kotlin/Java, Swift/Objective-C, C++).BasicMessageChannel - Pigeon: A code-generation tool that creates type-safe Platform Channels.
- Platform View: A mechanism to embed native UI components (e.g., Android , iOS
View) directly into the Flutter widget tree.UIView - JS Interop: The modern, Wasm-compatible approach to interacting with JavaScript and DOM APIs using and
package:web.dart:js_interop
- FFI (Foreign Function Interface): 库,用于将Dart直接绑定到原生C/C++ API。
dart:ffi - Platform Channel: 异步消息传递系统(、
MethodChannel),连接Dart客户端(UI)与宿主平台(Kotlin/Java、Swift/Objective-C、C++)。BasicMessageChannel - Pigeon: 一种代码生成工具,用于创建类型安全的Platform Channel。
- Platform View: 一种将原生UI组件(如Android 、iOS
View)直接嵌入Flutter组件树的机制。UIView - JS Interop: 兼容Wasm的现代交互方式,通过和
package:web与JavaScript及DOM API交互。dart:js_interop
Binding to Native C/C++ Code (FFI)
绑定原生C/C++代码(FFI)
Use FFI to execute high-performance native code or utilize existing C/C++ libraries without the overhead of asynchronous Platform Channels.
当需要执行高性能原生代码,或使用现有C/C++库且不想承担异步Platform Channel的开销时,可使用FFI。
Project Setup
项目设置
- If creating a standard C/C++ integration (Recommended since Flutter 3.38): Use the template. This utilizes
package_ffihooks to compile native code, eliminating the need for OS-specific build files (CMake, build.gradle, podspec).build.dartbashflutter create --template=package_ffi <package_name> - If requiring access to the Flutter Plugin API or Play Services: Use the legacy template.
plugin_ffibashflutter create --template=plugin_ffi <plugin_name>
- 若创建标准C/C++集成(Flutter 3.38及以上版本推荐): 使用模板。该模板利用
package_ffi钩子编译原生代码,无需OS专属构建文件(CMake、build.gradle、podspec)。build.dartbashflutter create --template=package_ffi <package_name> - 若需要访问Flutter Plugin API或Play Services: 使用旧版模板。
plugin_ffibashflutter create --template=plugin_ffi <plugin_name>
Implementation Rules
实现规则
- Symbol Visibility: Always mark C++ symbols with and prevent linker discarding during link-time optimization (LTO).
extern "C"cppextern "C" __attribute__((visibility("default"))) __attribute__((used)) - Dynamic Library Naming (Apple Platforms): Ensure your hook produces the exact same filename across all target architectures (e.g.,
build.dartvsarm64) and SDKs (x86_64vsiphoneos). Do not append architecture suffixes to theiphonesimulatoror.dylibnames..framework - Binding Generation: Always use to generate Dart bindings from your C headers (
package:ffigen). Configure this in.h.ffigen.yaml
- 符号可见性: 务必用标记C++符号,并在链接时优化(LTO)过程中防止链接器丢弃符号。
extern "C"cppextern "C" __attribute__((visibility("default"))) __attribute__((used)) - 动态库命名(Apple平台): 确保钩子在所有目标架构(如
build.dart与arm64)及SDK(x86_64与iphoneos)下生成完全相同的文件名。不要在iphonesimulator或.dylib名称后添加架构后缀。.framework - 绑定生成: 务必使用从C头文件(
package:ffigen)生成Dart绑定。在.h中进行配置。ffigen.yaml
Implementing Platform Channels & Pigeon
实现Platform Channel与Pigeon
Use Platform Channels when you need to interact with platform-specific APIs (e.g., Battery, Bluetooth, OS-level services) using the platform's native language.
当需要使用平台原生语言调用平台专属API(如电池、蓝牙、系统级服务)时,可使用Platform Channel。
Pigeon (Type-Safe Channels)
Pigeon(类型安全Channel)
Always prefer over raw implementations for complex or frequently used APIs.
package:pigeonMethodChannel- Define the messaging protocol in a standalone Dart file using Pigeon annotations ().
@HostApi() - Generate the host (Kotlin/Swift/C++) and client (Dart) code.
- Implement the generated interfaces on the native side.
对于复杂或频繁使用的API,务必优先使用而非原生实现。
package:pigeonMethodChannel- 在独立Dart文件中使用Pigeon注解()定义消息协议。
@HostApi() - 生成宿主端(Kotlin/Swift/C++)与客户端(Dart)代码。
- 在原生端实现生成的接口。
Threading Rules
线程规则
- Main Thread Requirement: Always invoke channel methods destined for Flutter on the platform's main thread (UI thread).
- Background Execution: If executing channel handlers on a background thread (Android/iOS), you must use the Task Queue API ().
makeBackgroundTaskQueue() - Isolates: To use plugins/channels from a Dart background , ensure it is registered using
Isolate.BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken)
- 主线程要求: 调用目标为Flutter的Channel方法时,务必在平台主线程(UI线程)执行。
- 后台执行: 若在后台线程(Android/iOS)执行Channel处理器,必须使用任务队列API()。
makeBackgroundTaskQueue() - Isolate: 若要在Dart后台中使用插件/Channel,需确保通过
Isolate完成注册。BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken)
Hosting Native Platform Views
托管原生平台视图
Use Platform Views to embed native UI components (e.g., Google Maps, native video players) into the Flutter widget tree.
当需要将原生UI组件(如谷歌地图、原生视频播放器)嵌入Flutter组件树时,可使用Platform View。
Android Platform Views
Android平台视图
Evaluate the trade-offs between the two rendering modes and select the appropriate one:
- If requiring perfect fidelity, accessibility, or SurfaceView support: Use Hybrid Composition (+
PlatformViewLink). This appends the native view to the hierarchy but may reduce Flutter's rendering performance.AndroidViewSurface - If prioritizing Flutter rendering performance and transformations: Use Texture Layer (). This renders the native view into a texture. Note: Quick scrolling may drop frames, and
AndroidViewis problematic.SurfaceView
评估两种渲染模式的利弊,选择合适的模式:
- 若需要完美的保真度、无障碍支持或SurfaceView支持: 使用Hybrid Composition(+
PlatformViewLink)。它会将原生视图添加到层级结构中,但可能会降低Flutter的渲染性能。AndroidViewSurface - 若优先考虑Flutter的渲染性能和变换效果: 使用Texture Layer()。它会将原生视图渲染为纹理。注意:快速滚动可能会丢帧,且
AndroidView存在兼容性问题。SurfaceView
iOS Platform Views
iOS平台视图
- iOS exclusively uses Hybrid Composition.
- Implement and
FlutterPlatformViewFactoryin Swift or Objective-C.FlutterPlatformView - Use the widget on the Dart side.
UiKitView - Limitation: and
ShaderMaskwidgets cannot be applied to iOS Platform Views.ColorFiltered
- iOS仅支持Hybrid Composition。
- 在Swift或Objective-C中实现和
FlutterPlatformViewFactory。FlutterPlatformView - 在Dart端使用组件。
UiKitView - 限制: 和
ShaderMask组件无法应用于iOS Platform View。ColorFiltered
Integrating Web Content & Wasm
集成Web内容与Wasm
Flutter Web supports compiling to WebAssembly (Wasm) for improved performance and multi-threading.
Flutter Web支持编译为WebAssembly(Wasm)以提升性能并实现多线程。
Wasm Compilation
Wasm编译
- Compile to Wasm using: .
flutter build web --wasm - Server Configuration: To enable multi-threading, configure your HTTP server to emit the following headers:
- (or
Cross-Origin-Embedder-Policy: credentialless)require-corp Cross-Origin-Opener-Policy: same-origin
- Limitation: WasmGC is not currently supported on iOS browsers (WebKit limitation). Flutter will automatically fall back to JavaScript if WasmGC is unavailable.
- 使用以下命令编译为Wasm:。
flutter build web --wasm - 服务器配置: 若要启用多线程,需配置HTTP服务器发送以下响应头:
- (或
Cross-Origin-Embedder-Policy: credentialless)require-corp Cross-Origin-Opener-Policy: same-origin
- 限制: iOS浏览器(WebKit)目前不支持WasmGC。若WasmGC不可用,Flutter会自动回退到JavaScript。
Web Interop
Web互操作
- If writing new web-specific code: Strictly use and
package:web.dart:js_interop - Do NOT use: ,
dart:html, ordart:js. These are incompatible with Wasm compilation.package:js - Embedding HTML: Use to inject arbitrary HTML elements (like
HtmlElementView.fromTagName) into the Flutter Web DOM.<video>
- 若编写新的Web专属代码: 严格使用和
package:web。dart:js_interop - 禁止使用: 、
dart:html或dart:js。这些库与Wasm编译不兼容。package:js - 嵌入HTML: 使用将任意HTML元素(如
HtmlElementView.fromTagName)注入Flutter Web的DOM中。<video>
Workflows
工作流程
Workflow: Creating a Native FFI Integration
工作流程:创建原生FFI集成
Use this workflow when binding to a C/C++ library.
- Task Progress:
- 1. Run .
flutter create --template=package_ffi <name> - 2. Place C/C++ source code in the directory.
src/ - 3. Ensure all exported C++ functions are wrapped in and visibility attributes.
extern "C" - 4. Configure to point to your header files.
ffigen.yaml - 5. Run to generate Dart bindings.
dart run ffigen - 6. Modify if linking against pre-compiled or system libraries.
hook/build.dart - 7. Run validator -> -> review errors -> fix.
flutter test
- 1. Run
当绑定到C/C++库时,使用此工作流程。
- 任务进度:
- 1. 运行。
flutter create --template=package_ffi <name> - 2. 将C/C++源代码放入目录。
src/ - 3. 确保所有导出的C++函数都用和可见性属性包裹。
extern "C" - 4. 配置指向你的头文件。
ffigen.yaml - 5. 运行生成Dart绑定。
dart run ffigen - 6. 若链接预编译或系统库,修改。
hook/build.dart - 7. 运行验证器 -> -> 查看错误 -> 修复问题。
flutter test
- 1. 运行
Workflow: Implementing a Type-Safe Platform Channel (Pigeon)
工作流程:实现类型安全的Platform Channel(Pigeon)
Use this workflow when you need to call Kotlin/Swift APIs from Dart.
- Task Progress:
- 1. Add to
pigeon.dev_dependencies - 2. Create and define data classes and
pigeons/messages.dartabstract classes.@HostApi() - 3. Run the Pigeon generator script to output Dart, Kotlin, and Swift files.
- 4. Android: Implement the generated interface in or your Plugin class.
MainActivity.kt - 5. iOS: Implement the generated protocol in or your Plugin class.
AppDelegate.swift - 6. Dart: Import the generated Dart file and call the API methods.
- 7. Run validator -> verify cross-platform compilation -> review errors -> fix.
- 1. Add
当需要从Dart调用Kotlin/Swift API时,使用此工作流程。
- 任务进度:
- 1. 在中添加
dev_dependencies。pigeon - 2. 创建,定义数据类和
pigeons/messages.dart抽象类。@HostApi() - 3. 运行Pigeon生成脚本,输出Dart、Kotlin和Swift文件。
- 4. Android: 在或你的Plugin类中实现生成的接口。
MainActivity.kt - 5. iOS: 在或你的Plugin类中实现生成的协议。
AppDelegate.swift - 6. Dart: 导入生成的Dart文件并调用API方法。
- 7. 运行验证器 -> 验证跨平台编译 -> 查看错误 -> 修复问题。
- 1. 在
Workflow: Embedding a Native Platform View
工作流程:嵌入原生平台视图
Use this workflow when embedding a native UI component (e.g., a native map or camera view).
- Task Progress:
- 1. Dart: Create a widget that conditionally returns (or
AndroidView) for Android, andPlatformViewLinkfor iOS based onUiKitView.defaultTargetPlatform - 2. Android: Create a class implementing that returns the native Android
PlatformView.View - 3. Android: Create a and register it in
PlatformViewFactory.configureFlutterEngine - 4. iOS: Create a class implementing that returns the native
FlutterPlatformView.UIView - 5. iOS: Create a and register it in
FlutterPlatformViewFactory.application:didFinishLaunchingWithOptions: - 6. Run validator -> test on physical Android and iOS devices -> review UI clipping/scrolling issues -> fix.
- 1. Dart: Create a widget that conditionally returns
当需要嵌入原生UI组件(如原生地图或相机视图)时,使用此工作流程。
- 任务进度:
- 1. Dart: 创建一个组件,根据为Android返回
defaultTargetPlatform(或AndroidView),为iOS返回PlatformViewLink。UiKitView - 2. Android: 创建实现的类,返回原生Android
PlatformView。View - 3. Android: 创建并在
PlatformViewFactory中注册。configureFlutterEngine - 4. iOS: 创建实现的类,返回原生
FlutterPlatformView。UIView - 5. iOS: 创建并在
FlutterPlatformViewFactory中注册。application:didFinishLaunchingWithOptions: - 6. 运行验证器 -> 在Android和iOS真机上测试 -> 查看UI裁剪/滚动问题 -> 修复问题。
- 1. Dart: 创建一个组件,根据