Integrating Platform-Specific Code in Flutter Contents Core Concepts & Terminology Binding to Native C/C++ Code (FFI) Implementing Platform Channels & Pigeon Hosting Native Platform Views Integrating Web Content & Wasm Workflows Core Concepts & Terminology FFI (Foreign Function Interface): The dart:ffi library used to bind Dart directly to native C/C++ APIs. Platform Channel: The asynchronous message-passing system ( MethodChannel , BasicMessageChannel ) connecting the Dart client (UI) to the host platform (Kotlin/Java, Swift/Objective-C, C++). Pigeon: A code-generation tool that creates type-safe Platform Channels. Platform View: A mechanism to embed native UI components (e.g., Android View , iOS UIView ) directly into the Flutter widget tree. JS Interop: The modern, Wasm-compatible approach to interacting with JavaScript and DOM APIs using package:web and dart:js_interop . Binding to Native C/C++ Code (FFI) Use FFI to execute high-performance native code or utilize existing C/C++ libraries without the overhead of asynchronous Platform Channels. Project Setup If creating a standard C/C++ integration (Recommended since Flutter 3.38): Use the package_ffi template. This utilizes build.dart hooks to compile native code, eliminating the need for OS-specific build files (CMake, build.gradle, podspec). flutter create --template = package_ffi < package_name
If requiring access to the Flutter Plugin API or Play Services: Use the legacy plugin_ffi template. flutter create --template = plugin_ffi < plugin_name
Implementation Rules Symbol Visibility: Always mark C++ symbols with extern "C" and prevent linker discarding during link-time optimization (LTO). extern "C" attribute ( ( visibility ( "default" ) ) ) attribute ( ( used ) ) Dynamic Library Naming (Apple Platforms): Ensure your build.dart hook produces the exact same filename across all target architectures (e.g., arm64 vs x86_64 ) and SDKs ( iphoneos vs iphonesimulator ). Do not append architecture suffixes to the .dylib or .framework names. Binding Generation: Always use package:ffigen to generate Dart bindings from your C headers ( .h ). Configure this in ffigen.yaml . Implementing Platform Channels & 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. Pigeon (Type-Safe Channels) Always prefer package:pigeon over raw MethodChannel implementations for complex or frequently used APIs. 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. 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 Isolate , ensure it is registered using 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. Android Platform Views 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 + AndroidViewSurface ). This appends the native view to the hierarchy but may reduce Flutter's rendering performance. If prioritizing Flutter rendering performance and transformations: Use Texture Layer ( AndroidView ). This renders the native view into a texture. Note: Quick scrolling may drop frames, and SurfaceView is problematic. iOS Platform Views iOS exclusively uses Hybrid Composition. Implement FlutterPlatformViewFactory and FlutterPlatformView in Swift or Objective-C. Use the UiKitView widget on the Dart side. Limitation: ShaderMask and ColorFiltered widgets cannot be applied to iOS Platform Views. Integrating Web Content & Wasm Flutter Web supports compiling to WebAssembly (Wasm) for improved performance and multi-threading. Wasm Compilation Compile to Wasm using: flutter build web --wasm . Server Configuration: To enable multi-threading, configure your HTTP server to emit the following headers: Cross-Origin-Embedder-Policy: credentialless (or 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. Web Interop If writing new web-specific code: Strictly use package:web and dart:js_interop . Do NOT use: dart:html , dart:js , or package:js . These are incompatible with Wasm compilation. Embedding HTML: Use HtmlElementView.fromTagName to inject arbitrary HTML elements (like