flutter-plugins

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

flutter-plugin-generator

flutter-plugin-generator

Goal

目标

Scaffolds and configures Flutter plugin packages, handling standard method channels, FFI integrations, and federated plugin architectures. It configures platform-specific native code environments, implements Android v2 embedding lifecycle interfaces, and establishes platform interface packages.
搭建并配置Flutter插件包,处理标准方法通道、FFI集成和联合插件架构。它会配置平台特定的原生代码环境,实现Android v2嵌入生命周期接口,并建立平台接口包。

Decision Logic

决策逻辑

Use the following decision tree to determine the plugin architecture and template:
  1. Does the plugin require C/C++ native code via
    dart:ffi
    ?
    • Yes: Use
      --template=plugin_ffi
      .
      • Note: FFI plugins support bundling native code and method channel registration, but not method channels themselves.
    • No: Proceed to step 2.
  2. Does the plugin require BOTH
    dart:ffi
    and Method Channels?
    • Yes: Use
      --template=plugin
      (Non-FFI). You must configure FFI manually within the standard plugin structure.
    • No: Proceed to step 3.
  3. Will the plugin be developed by multiple teams or require highly decoupled platform implementations?
    • Yes: Implement a Package-Separated Federated Plugin (App-facing package, Platform Interface package, Platform Implementation packages).
    • No: Implement a standard monolithic plugin.
使用以下决策树确定插件架构和模板:
  1. 插件是否需要通过
    dart:ffi
    调用C/C++原生代码?
    • 是: 使用
      --template=plugin_ffi
      • 注意: FFI插件支持打包原生代码和方法通道注册,但不支持方法通道本身。
    • 否: 进入步骤2。
  2. 插件是否同时需要
    dart:ffi
    和方法通道?
    • 是: 使用
      --template=plugin
      (非FFI)。你必须在标准插件结构中手动配置FFI。
    • 否: 进入步骤3。
  3. 该插件是否会由多个团队开发,或者需要高度解耦的平台实现?
    • 是: 实现包分离的联合插件(面向应用的包、平台接口包、平台实现包)。
    • 否: 实现标准的单体插件。

Instructions

使用说明

  1. Gather Plugin Requirements STOP AND ASK THE USER:
    • What is the plugin name?
    • What is the organization name (reverse domain notation, e.g.,
      com.example
      )?
    • Which platforms should be supported (comma-separated:
      android,ios,web,linux,macos,windows
      )?
    • Do you need an FFI plugin or a standard Method Channel plugin?
    • Do you prefer Java or Kotlin for Android? Objective-C or Swift for iOS?
    • Should this be a federated plugin?
  2. Generate the Plugin Package Execute the Flutter CLI command based on the user's parameters.
    Standard Plugin Example:
    bash
    flutter create --org com.example --template=plugin --platforms=android,ios,macos -a kotlin -i swift my_plugin
    FFI Plugin Example:
    bash
    flutter create --template=plugin_ffi my_ffi_plugin
  3. Configure Federated Plugin Architecture (If Applicable) If the user requested a federated plugin, configure the
    pubspec.yaml
    of the app-facing package to endorse the platform implementations.
    yaml
    # App-facing pubspec.yaml
    flutter:
      plugin:
        platforms:
          android:
            default_package: my_plugin_android
          windows:
            default_package: my_plugin_windows
    
    dependencies:
      my_plugin_android: ^1.0.0
      my_plugin_windows: ^1.0.0
    For the platform implementation packages, define the
    implements
    key:
    yaml
    # Platform implementation pubspec.yaml (e.g., my_plugin_windows)
    flutter:
      plugin:
        implements: my_plugin
        platforms:
          windows:
            pluginClass: MyPlugin
  4. Prepare Native Environments for Editing Before modifying native code, you MUST build the example app to resolve dependencies and generate necessary files.
    bash
    cd my_plugin/example
    flutter build apk --config-only # For Android
    flutter build ios --no-codesign --config-only # For iOS
    flutter build windows # For Windows
  5. Implement Android v2 Embedding Lifecycle Modify the Android plugin class (e.g.,
    android/src/main/kotlin/com/example/my_plugin/MyPlugin.kt
    ). Extract logic from
    registerWith()
    into a private method shared with
    onAttachedToEngine()
    . Implement
    ActivityAware
    or
    ServiceAware
    if context is needed.
    kotlin
    package com.example.my_plugin
    
    import androidx.annotation.NonNull
    import io.flutter.embedding.engine.plugins.FlutterPlugin
    import io.flutter.embedding.engine.plugins.activity.ActivityAware
    import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
    import io.flutter.plugin.common.MethodCall
    import io.flutter.plugin.common.MethodChannel
    import io.flutter.plugin.common.MethodChannel.MethodCallHandler
    import io.flutter.plugin.common.MethodChannel.Result
    
    class MyPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
      private lateinit var channel : MethodChannel
    
      override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        setupChannel(flutterPluginBinding.binaryMessenger)
      }
    
      // Shared private method for v1 and v2 embedding compatibility
      private fun setupChannel(messenger: BinaryMessenger) {
        channel = MethodChannel(messenger, "my_plugin")
        channel.setMethodCallHandler(this)
      }
    
      override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
        if (call.method == "getPlatformVersion") {
          result.success("Android ${android.os.Build.VERSION.RELEASE}")
        } else {
          result.notImplemented()
        }
      }
    
      override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
      }
    
      override fun onAttachedToActivity(binding: ActivityPluginBinding) {
        // Handle Activity attachment
      }
    
      override fun onDetachedFromActivityForConfigChanges() {}
      override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {}
      override fun onDetachedFromActivity() {}
    }
  6. Validate and Fix Run the plugin tests and analyzer to ensure the generated code is valid.
    bash
    cd my_plugin
    flutter analyze
    flutter test
    If the analyzer reports missing dependencies or unresolved native symbols, verify that step 4 (building the example app) was executed successfully. Fix any missing imports in the native code blocks.
  1. 收集插件需求 请先询问用户以下信息:
    • 插件名称是什么?
    • 组织名称是什么(反向域名格式,例如
      com.example
      )?
    • 需要支持哪些平台(逗号分隔:
      android,ios,web,linux,macos,windows
      )?
    • 你需要FFI插件还是标准方法通道插件?
    • Android端你偏好Java还是Kotlin?iOS端偏好Objective-C还是Swift?
    • 是否需要做成联合插件?
  2. 生成插件包 根据用户参数执行Flutter CLI命令。
    标准插件示例:
    bash
    flutter create --org com.example --template=plugin --platforms=android,ios,macos -a kotlin -i swift my_plugin
    FFI插件示例:
    bash
    flutter create --template=plugin_ffi my_ffi_plugin
  3. 配置联合插件架构(如果适用) 如果用户要求使用联合插件,配置面向应用的包的
    pubspec.yaml
    来指定默认的平台实现。
    yaml
    # 面向应用的pubspec.yaml
    flutter:
      plugin:
        platforms:
          android:
            default_package: my_plugin_android
          windows:
            default_package: my_plugin_windows
    
    dependencies:
      my_plugin_android: ^1.0.0
      my_plugin_windows: ^1.0.0
    对于平台实现包,定义
    implements
    字段:
    yaml
    # 平台实现pubspec.yaml(例如my_plugin_windows)
    flutter:
      plugin:
        implements: my_plugin
        platforms:
          windows:
            pluginClass: MyPlugin
  4. 准备原生开发环境 修改原生代码之前,你必须构建示例应用来解析依赖并生成必要的文件。
    bash
    cd my_plugin/example
    flutter build apk --config-only # For Android
    flutter build ios --no-codesign --config-only # For iOS
    flutter build windows # For Windows
  5. 实现Android v2嵌入生命周期 修改Android插件类(例如
    android/src/main/kotlin/com/example/my_plugin/MyPlugin.kt
    )。将
    registerWith()
    中的逻辑提取到一个私有方法,供
    onAttachedToEngine()
    共享调用。如果需要上下文,实现
    ActivityAware
    ServiceAware
    接口。
    kotlin
    package com.example.my_plugin
    
    import androidx.annotation.NonNull
    import io.flutter.embedding.engine.plugins.FlutterPlugin
    import io.flutter.embedding.engine.plugins.activity.ActivityAware
    import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
    import io.flutter.plugin.common.MethodCall
    import io.flutter.plugin.common.MethodChannel
    import io.flutter.plugin.common.MethodChannel.MethodCallHandler
    import io.flutter.plugin.common.MethodChannel.Result
    
    class MyPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
      private lateinit var channel : MethodChannel
    
      override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        setupChannel(flutterPluginBinding.binaryMessenger)
      }
    
      // 共享私有方法,兼容v1和v2嵌入
      private fun setupChannel(messenger: BinaryMessenger) {
        channel = MethodChannel(messenger, "my_plugin")
        channel.setMethodCallHandler(this)
      }
    
      override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
        if (call.method == "getPlatformVersion") {
          result.success("Android ${android.os.Build.VERSION.RELEASE}")
        } else {
          result.notImplemented()
        }
      }
    
      override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
      }
    
      override fun onAttachedToActivity(binding: ActivityPluginBinding) {
        // 处理Activity绑定
      }
    
      override fun onDetachedFromActivityForConfigChanges() {}
      override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {}
      override fun onDetachedFromActivity() {}
    }
  6. 验证与修复 运行插件测试和分析器,确保生成的代码有效。
    bash
    cd my_plugin
    flutter analyze
    flutter test
    如果分析器报告缺失依赖或无法解析原生符号,请确认步骤4(构建示例应用)已成功执行。修复原生代码块中所有缺失的导入。

Constraints

约束条件

  • Never attempt to use Method Channels inside a package created with
    --template=plugin_ffi
    . If both are required, use
    --template=plugin
    .
  • Always build the example project (
    flutter build <platform>
    ) at least once before attempting to edit or analyze native Android (
    build.gradle
    ), iOS (
    .xcworkspace
    ), or Windows (
    .sln
    ) files.
  • Never leave public members undocumented in the Dart API (
    lib/<package_name>.dart
    ).
  • Always use the v2 Android embedding (
    FlutterPlugin
    ). Do not rely solely on the deprecated
    PluginRegistry.Registrar
    .
  • Never edit the
    .android
    or
    .ios
    directories inside a Flutter module; only edit the native code inside the plugin's
    android/
    or
    ios/
    directories.
  • 绝对不要在使用
    --template=plugin_ffi
    创建的包中使用方法通道。如果两者都需要,请使用
    --template=plugin
  • 必须在编辑或分析原生Android(
    build.gradle
    )、iOS(
    .xcworkspace
    )或Windows(
    .sln
    )文件之前,至少构建一次示例项目(
    flutter build <platform>
    )。
  • 不要在Dart API(
    lib/<package_name>.dart
    )中留下未文档化的公共成员。
  • 必须使用v2 Android嵌入(
    FlutterPlugin
    )。不要仅依赖已弃用的
    PluginRegistry.Registrar
  • 绝对不要编辑Flutter模块中的
    .android
    .ios
    目录;仅编辑插件
    android/
    ios/
    目录下的原生代码。