flutter-building-plugins by flutter/skills
npx skills add https://github.com/flutter/skills --skill flutter-building-plugins实现联合插件以将插件的 API 拆分到多个包中,允许独立的团队构建特定平台的实现。将联合插件结构化为三个不同的组件:
my_plugin_android、my_plugin_windows)。根据您的原生互操作性需求选择正确的插件模板:
--template=plugin): 用于通过方法通道访问平台特定的 API(例如 Android SDK、iOS 框架)。--template=plugin_ffi): 用于访问 C/C++ 原生库、在 Android 上配置 Google Play 服务或在 iOS/macOS 上使用静态链接。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
按照此工作流初始化一个新的插件包。
任务进度:
flutter create 命令。条件初始化:
如果创建标准插件: 运行以下命令,指定您支持的平台、组织以及首选语言(默认为 Swift 和 Kotlin):
flutter create --template=plugin \
--platforms=android,ios,web,linux,macos,windows \
--org com.example.organization \
-i objc -a java \
my_plugin
如果创建 FFI 插件: 运行以下命令以生成一个项目,其中 Dart 代码位于 lib 目录(使用 dart:ffi),原生源代码位于 src 目录(包含 CMakeLists.txt):
flutter create --template=plugin_ffi my_ffi_plugin
始终使用 Android Studio 编辑 Android 平台代码,以确保正确的代码补全和 Gradle 同步。
任务进度:
FlutterPlugin 和生命周期感知接口。registerWith 逻辑。生成构建文件: 在编辑之前至少构建一次代码以解析依赖项。
cd example flutter build apk --config-only
在 IDE 中打开: 启动 Android Studio 并打开 example/android/build.gradle 或 example/android/build.gradle.kts 文件。
定位源代码: 导航到您的插件源代码位置 java/<组织路径>/<插件名称>。
实现 V2 嵌入:
* 实现 FlutterPlugin 接口。
* 确保您的插件类有一个公共构造函数。
* 从遗留的 registerWith() 方法和新的 onAttachedToEngine() 方法中提取共享的初始化逻辑到一个单一的私有方法中。两个入口点都必须调用此私有方法,以在保持向后兼容性的同时避免逻辑重复。
实现生命周期接口:
* 如果您的插件需要 Activity 引用: 实现 ActivityAware 接口并处理 onAttachedToActivity、onDetachedFromActivityForConfigChanges、onReattachedToActivityForConfigChanges 和 onDetachedFromActivity 回调。
* 如果您的插件在后台 Service 中运行: 实现 ServiceAware 接口。
更新示例应用: 确保示例应用的 MainActivity.java 扩展了 v2 嵌入的 io.flutter.embedding.android.FlutterActivity。
记录 API: 记录您的 Android 实现中所有未覆盖的公共成员。
始终使用 Visual Studio 编辑 Windows 平台代码。
任务进度:
生成构建文件:
cd example flutter build windows
在 IDE 中打开: 启动 Visual Studio 并打开 example/build/windows/hello_example.sln 文件。
定位源代码: 在解决方案资源管理器中导航到 hello_plugin/Source Files 和 hello_plugin/Header Files。
重新构建: 在对 C++ 插件代码进行更改后,在运行应用程序之前,您_必须_在 Visual Studio 中重新构建解决方案,否则将使用过时的插件二进制文件。
使用此工作流为现有插件添加对其他平台的支持。
任务进度:
运行创建命令: 导航到您现有插件的根目录并运行:
flutter create --template=plugin --platforms=web,macos .
更新 Podspecs: 如果添加 iOS 或 macOS 支持,请打开生成的 .podspec 文件并配置所需的依赖项和部署目标。
一个高保真度的 Android 插件示例,实现了 FlutterPlugin 和 ActivityAware,同时保持了遗留兼容性。
package com.example.myplugin;
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;
import io.flutter.plugin.common.PluginRegistry.Registrar;
/** MyPlugin */
public class MyPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
private MethodChannel channel;
// Public constructor required for v2 embedding
public MyPlugin() {}
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
setupChannel(flutterPluginBinding.getBinaryMessenger());
}
// Legacy v1 embedding support
public static void registerWith(Registrar registrar) {
MyPlugin plugin = new MyPlugin();
plugin.setupChannel(registrar.messenger());
}
// Shared initialization logic
private void setupChannel(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "my_plugin");
channel.setMethodCallHandler(this);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
}
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
// Handle Activity attachment
}
@Override
public void onDetachedFromActivityForConfigChanges() {
// Handle config changes
}
@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
// Handle reattachment
}
@Override
public void onDetachedFromActivity() {
// Clean up Activity references
}
}
每周安装量
1.8K
代码库
GitHub 星标数
792
首次出现
12 天前
安全审计
已安装于
codex1.7K
gemini-cli1.7K
opencode1.7K
github-copilot1.7K
kimi-cli1.7K
cursor1.7K
Implement federated plugins to split a plugin's API across multiple packages, allowing independent teams to build platform-specific implementations. Structure federated plugins into three distinct components:
my_plugin_android, my_plugin_windows).Choose the correct plugin template based on your native interoperability requirements:
--template=plugin): Use for accessing platform-specific APIs (e.g., Android SDK, iOS frameworks) via Method Channels.--template=plugin_ffi): Use for accessing C/C++ native libraries, configuring Google Play services on Android, or using static linking on iOS/macOS.
Follow this workflow to initialize a new plugin package.
Task Progress:
flutter create command.Conditional Initialization:
If creating a STANDARD plugin: Run the following command, specifying your supported platforms, organization, and preferred languages (defaults are Swift and Kotlin):
flutter create --template=plugin \
--platforms=android,ios,web,linux,macos,windows \
--org com.example.organization \
-i objc -a java \
my_plugin
If creating an FFI plugin: Run the following command to generate a project with Dart code in lib (using dart:ffi) and native source code in src (with a CMakeLists.txt):
flutter create --template=plugin_ffi my_ffi_plugin
Always edit Android platform code using Android Studio to ensure proper code completion and Gradle synchronization.
Task Progress:
FlutterPlugin and lifecycle-aware interfaces.registerWith logic.Generate Build Files: Build the code at least once before editing to resolve dependencies.
cd example
flutter build apk --config-only
Open in IDE: Launch Android Studio and open the example/android/build.gradle or example/android/build.gradle.kts file.
Locate Source: Navigate to your plugin's source code at java/<organization-path>/<PluginName>.
Implement V2 Embedding:
FlutterPlugin interface.registerWith() method and the new onAttachedToEngine() method into a single private method. Both entry points must call this private method to maintain backward compatibility without duplicating logic.Always edit Windows platform code using Visual Studio.
Task Progress:
Generate Build Files:
cd example
flutter build windows
Open in IDE: Launch Visual Studio and open the example/build/windows/hello_example.sln file.
Locate Source: Navigate to hello_plugin/Source Files and hello_plugin/Header Files in the Solution Explorer.
Rebuild: After making changes to the C++ plugin code, you must rebuild the solution in Visual Studio before running the app, or the outdated plugin binary will be used.
Use this workflow to retrofit an existing plugin with support for additional platforms.
Task Progress:
Run Create Command: Navigate to the root directory of your existing plugin and run:
flutter create --template=plugin --platforms=web,macos .
Update Podspecs: If adding iOS or macOS support, open the generated .podspec file and configure the required dependencies and deployment targets.
High-fidelity example of an Android plugin implementing FlutterPlugin and ActivityAware while maintaining legacy compatibility.
package com.example.myplugin;
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;
import io.flutter.plugin.common.PluginRegistry.Registrar;
/** MyPlugin */
public class MyPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
private MethodChannel channel;
// Public constructor required for v2 embedding
public MyPlugin() {}
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
setupChannel(flutterPluginBinding.getBinaryMessenger());
}
// Legacy v1 embedding support
public static void registerWith(Registrar registrar) {
MyPlugin plugin = new MyPlugin();
plugin.setupChannel(registrar.messenger());
}
// Shared initialization logic
private void setupChannel(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "my_plugin");
channel.setMethodCallHandler(this);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
}
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
// Handle Activity attachment
}
@Override
public void onDetachedFromActivityForConfigChanges() {
// Handle config changes
}
@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
// Handle reattachment
}
@Override
public void onDetachedFromActivity() {
// Clean up Activity references
}
}
Weekly Installs
1.8K
Repository
GitHub Stars
792
First Seen
12 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex1.7K
gemini-cli1.7K
opencode1.7K
github-copilot1.7K
kimi-cli1.7K
cursor1.7K
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装
Implement Lifecycle Interfaces:
Activity reference: Implement the ActivityAware interface and handle the onAttachedToActivity, onDetachedFromActivityForConfigChanges, onReattachedToActivityForConfigChanges, and onDetachedFromActivity callbacks.Service: Implement the ServiceAware interface.Update Example App: Ensure the example app's MainActivity.java extends the v2 embedding io.flutter.embedding.android.FlutterActivity.
Document API: Document all non-overridden public members in your Android implementation.