Agent SkillsMimicHunterZ/PocketMind › flutter-native-interop

flutter-native-interop

GitHub

指导Flutter应用与Android、iOS及Web原生代码集成,涵盖FFI、Platform Channels、Platform Views及JS Interop策略选择与实现。

.claude/skills/flutter-native-interop/SKILL.md MimicHunterZ/PocketMind

Trigger Scenarios

需要调用原生C/C++代码 需要访问操作系统特定API 需要在Flutter中嵌入原生UI组件 需要进行Web端JavaScript互操作

Install

npx skills add MimicHunterZ/PocketMind --skill flutter-native-interop -g -y
More Options

Non-standard path

npx skills add https://github.com/MimicHunterZ/PocketMind/tree/master/.claude/skills/flutter-native-interop -g -y

Use without installing

npx skills use MimicHunterZ/PocketMind@flutter-native-interop

指定 Agent (Claude Code)

npx skills add MimicHunterZ/PocketMind --skill flutter-native-interop -a claude-code -g -y

安装 repo 全部 skill

npx skills add MimicHunterZ/PocketMind --all -g -y

预览 repo 内 skill

npx skills add MimicHunterZ/PocketMind --list

SKILL.md

Frontmatter
{
    "name": "flutter-native-interop",
    "metadata": {
        "model": "models\/gemini-3.1-pro-preview",
        "last_modified": "Wed, 04 Mar 2026 19:26:40 GMT"
    },
    "description": "Interoperate with native APIs in a Flutter app on Android, iOS, and the web"
}

Flutter Platform Integration

Goal

Integrates Flutter applications with platform-specific code and native features across Android, iOS, and Web environments. Determines the optimal interoperability strategy (FFI, Platform Channels, Platform Views, or JS Interop) and implements the necessary Dart and native code bindings while adhering to thread safety, WebAssembly (Wasm) compatibility, and modern build hook standards.

Instructions

1. Determine Integration Strategy (Decision Logic)

Evaluate the user's requirements using the following decision tree to select the correct integration path:

  • Scenario A: Calling native C/C++ code.
    • Action: Use dart:ffi with the package_ffi template and build hooks.
    • Exception: If accessing the Flutter Plugin API or requiring static linking on iOS, use the legacy plugin_ffi template.
  • Scenario B: Calling OS-specific APIs (Java/Kotlin for Android, Swift/Obj-C for iOS).
    • Action: Use Platform Channels (MethodChannel) or the pigeon package for type-safe code generation.
  • Scenario C: Embedding native UI components into the Flutter widget tree.
    • Action: Use Platform Views (AndroidView / AndroidViewSurface for Android, UiKitView for iOS).
  • Scenario D: Web integration and JavaScript APIs.
    • Action: Use package:web and dart:js_interop (Wasm-compatible). Use HtmlElementView for embedding web content.

STOP AND ASK THE USER: "Which platform(s) are you targeting, and what specific native functionality or UI component do you need to integrate?"

2. Implement C/C++ Interop (dart:ffi)

If Scenario A is selected, implement the modern FFI architecture using build hooks (Flutter 3.38+).

  1. Generate the package:
    flutter create --template=package_ffi native_add
    
  2. Configure the build hook (hook/build.dart) to compile the native code:
    import 'package:hooks/hooks.dart';
    import 'package:native_toolchain_c/native_toolchain_c.dart';
    
    void main(List<String> args) async {
      await build(args, (config, output) async {
        final builder = CBuilder.library(
          name: 'native_add',
          assetId: 'native_add/src/native_add.dart',
          sources: ['src/native_add.c'],
        );
        await builder.run(config: config, output: output);
      });
    }
    
  3. Bind the native function in Dart (lib/src/native_add.dart):
    import 'dart:ffi';
    
    @Native<Int32 Function(Int32, Int32)>()
    external int sum(int a, int b);
    

3. Implement Platform Channels (MethodChannel)

If Scenario B is selected, implement asynchronous message passing.

  1. Dart Client Implementation:
    import 'package:flutter/services.dart';
    
    class NativeApi {
      static const platform = MethodChannel('com.example.app/channel');
    
      Future<String> getNativeData() async {
        try {
          final String result = await platform.invokeMethod('getData');
          return result;
        } on PlatformException catch (e) {
          return "Error: '${e.message}'.";
        }
      }
    }
    
  2. Android Host Implementation (Kotlin):
    import androidx.annotation.NonNull
    import io.flutter.embedding.android.FlutterActivity
    import io.flutter.embedding.engine.FlutterEngine
    import io.flutter.plugin.common.MethodChannel
    
    class MainActivity: FlutterActivity() {
      private val CHANNEL = "com.example.app/channel"
    
      override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
          if (call.method == "getData") {
            result.success("Data from Android")
          } else {
            result.notImplemented()
          }
        }
      }
    }
    
  3. iOS Host Implementation (Swift):
    import Flutter
    import UIKit
    
    @UIApplicationMain
    @objc class AppDelegate: FlutterAppDelegate {
      override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let channel = FlutterMethodChannel(name: "com.example.app/channel", binaryMessenger: controller.binaryMessenger)
    
        channel.setMethodCallHandler({
          (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
          if call.method == "getData" {
            result("Data from iOS")
          } else {
            result(FlutterMethodNotImplemented)
          }
        })
    
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
      }
    }
    

4. Implement Platform Views

If Scenario C is selected, embed native views.

  1. Dart Implementation (iOS Example):
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    Widget buildNativeView() {
      const String viewType = '<platform-view-type>';
      final Map<String, dynamic> creationParams = <String, dynamic>{};
    
      return UiKitView(
        viewType: viewType,
        layoutDirection: TextDirection.ltr,
        creationParams: creationParams,
        creationParamsCodec: const StandardMessageCodec(),
      );
    }
    
  2. iOS Factory Implementation (Swift):
    import Flutter
    import UIKit
    
    class FLNativeViewFactory: NSObject, FlutterPlatformViewFactory {
        private var messenger: FlutterBinaryMessenger
    
        init(messenger: FlutterBinaryMessenger) {
            self.messenger = messenger
            super.init()
        }
    
        func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
            return FLNativeView(frame: frame, viewIdentifier: viewId, arguments: args, binaryMessenger: messenger)
        }
    
        public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
              return FlutterStandardMessageCodec.sharedInstance()
        }
    }
    
    class FLNativeView: NSObject, FlutterPlatformView {
        private var _view: UIView
    
        init(frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?, binaryMessenger messenger: FlutterBinaryMessenger?) {
            _view = UIView()
            super.init()
            _view.backgroundColor = UIColor.blue
        }
    
        func view() -> UIView { return _view }
    }
    
    Validate-and-Fix: Ensure the factory is registered in AppDelegate.swift using registrar.register(factory, withId: "<platform-view-type>").

5. Implement Web Integration (Wasm & JS Interop)

If Scenario D is selected, implement Wasm-compatible web integrations.

  1. JS Interop (Dart):
    import 'dart:js_interop';
    import 'package:web/web.dart' as web;
    
    @JS('console.log')
    external void log(JSAny? value);
    
    void manipulateDOM() {
      final div = web.document.createElement('div') as web.HTMLDivElement;
      div.text = "Hello from Wasm-compatible Dart!";
      web.document.body?.append(div);
      log("DOM updated".toJS);
    }
    
  2. Embedding HTML Elements:
    import 'package:flutter/widgets.dart';
    import 'package:web/web.dart' as web;
    
    Widget buildVideoElement() {
      return HtmlElementView.fromTag('video', onElementCreated: (Object video) {
        final videoElement = video as web.HTMLVideoElement;
        videoElement.src = 'https://example.com/video.mp4';
        videoElement.style.width = '100%';
        videoElement.style.height = '100%';
      });
    }
    

Constraints

  • Thread Safety: Whenever you invoke a channel method on the platform side destined for Flutter, you MUST invoke it on the platform's main/UI thread. Use Handler(Looper.getMainLooper()).post (Android) or DispatchQueue.main.async (iOS) if jumping from a background thread.
  • WebAssembly Compatibility: DO NOT use dart:html, dart:js, or package:js. You MUST use package:web and dart:js_interop to ensure the app compiles to Wasm.
  • Wasm iOS Limitation: Flutter compiled to Wasm currently CANNOT run on the iOS version of any browser due to WebKit limitations. Ensure fallback to JS compilation is maintained.
  • FFI Naming: When implementing build.dart hooks for Apple platforms, dynamic libraries MUST have consistent filenames across all target architectures (e.g., do not use lib_arm64.dylib).
  • Platform View Performance: Handling SurfaceView on Android via Platform Views is problematic and should be avoided when possible. Prefer TextureLayerHybridComposition for better Flutter rendering performance.

Version History

  • c1dc382 Current 2026-08-20 13:17

Same Skill Collection

.claude/skills/asset-image-subsystem/SKILL.md
.claude/skills/baoyu-danger-x-to-markdown/SKILL.md
.claude/skills/flutter-accessibility/SKILL.md
.claude/skills/flutter-app-size/SKILL.md
.claude/skills/flutter-architecture/SKILL.md
.claude/skills/flutter-concurrency/SKILL.md
.claude/skills/flutter-environment-setup-linux/SKILL.md
.claude/skills/flutter-environment-setup-macos/SKILL.md
.claude/skills/flutter-environment-setup-windows/SKILL.md
.claude/skills/flutter-http-and-json/SKILL.md
.claude/skills/flutter-layout/SKILL.md
.claude/skills/flutter-localization/SKILL.md
.claude/skills/flutter-plugins/SKILL.md
.claude/skills/flutter-routing-and-navigation/SKILL.md
.claude/skills/flutter-testing/SKILL.md
.claude/skills/flutter-theming/SKILL.md
.claude/skills/headless-scraping/SKILL.md
.claude/skills/moai-lang-flutter/SKILL.md
.claude/skills/mobile-ai-chat-client/SKILL.md
.claude/skills/mobile-note-sync-architecture/SKILL.md
.claude/skills/note-resource-catalog-reliability/SKILL.md
.claude/skills/note-resource-event-driven-architecture/SKILL.md
.claude/skills/pocketmind-context-architecture/SKILL.md
.claude/skills/skill-creator/SKILL.md
backend/.claude/skills/code-reviewer/SKILL.md
.claude/skills/flutter-animation/SKILL.md
.claude/skills/flutter-caching/SKILL.md
.claude/skills/flutter-databases/SKILL.md
.claude/skills/flutter-form/SKILL.md
.claude/skills/flutter-home-screen-widget/SKILL.md
.claude/skills/flutter-performance/SKILL.md
.claude/skills/flutter-platform-views/SKILL.md
.claude/skills/flutter-state-management/SKILL.md

Metadata

Files
0
Version
c1dc382
Hash
80f5dc71
Indexed
2026-08-20 13:17

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-29 06:32
浙ICP备14020137号-1 $Carte des visiteurs$