Flutter发布插件:从开发到上架

一、创建插件项目

  1. 创建基础插件
bash 复制代码
# 创建插件项目
flutter create --template=plugin --org=com.example my_flutter_plugin

# 进入项目
cd my_flutter_plugin
  1. 项目结构

    my_flutter_plugin/
    ├── lib/
    │ └── my_flutter_plugin.dart # Dart主文件
    ├── android/ # Android实现
    ├── ios/ # iOS实现
    ├── example/ # 示例项目
    ├── pubspec.yaml # 依赖配置
    └── README.md # 说明文档

二、编写插件代码

  1. Dart接口文件 (lib/my_flutter_plugin.dart)
dart 复制代码
import 'dart:async';
import 'package:flutter/services.dart';

class MyFlutterPlugin {
  static const MethodChannel _channel = 
      MethodChannel('my_flutter_plugin');

  /// 获取平台版本
  static Future<String> getPlatformVersion() async {
    final String version = 
        await _channel.invokeMethod('getPlatformVersion');
    return version;
  }

  /// 自定义方法示例
  static Future<bool> showToast(String message) async {
    try {
      await _channel.invokeMethod('showToast', {'msg': message});
      return true;
    } catch (e) {
      print('Error: $e');
      return false;
    }
  }
}
  1. Android实现 (android/src/main/kotlin/.../MyFlutterPlugin.kt)
kotlin 复制代码
package com.example.my_flutter_plugin

import android.content.Context
import android.widget.Toast
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel

class MyFlutterPlugin: FlutterPlugin, MethodChannel.MethodCallHandler {
  private lateinit var channel: MethodChannel
  private lateinit var context: Context
  
  override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    context = flutterPluginBinding.applicationContext
    channel = MethodChannel(flutterPluginBinding.binaryMessenger, "my_flutter_plugin")
    channel.setMethodCallHandler(this)
  }
  
  override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
    when (call.method) {
      "getPlatformVersion" -> {
        result.success("Android ${android.os.Build.VERSION.RELEASE}")
      }
      "showToast" -> {
        val msg = call.argument<String>("msg")
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
        result.success(true)
      }
      else -> result.notImplemented()
    }
  }
  
  override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }
}
  1. iOS实现 (ios/Classes/MyFlutterPlugin.m)
objective-c 复制代码
#import "MyFlutterPlugin.h"
#import <UIKit/UIKit.h>

@implementation MyFlutterPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterMethodChannel* channel = [FlutterMethodChannel
      methodChannelWithName:@"my_flutter_plugin"
            binaryMessenger:[registrar messenger]];
  MyFlutterPlugin* instance = [[MyFlutterPlugin alloc] init];
  [registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  if ([@"getPlatformVersion" isEqualToString:call.method]) {
    result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
  } else if ([@"showToast" isEqualToString:call.method]) {
    NSString *message = call.arguments[@"msg"];
    UIAlertController *alert = [UIAlertController 
        alertControllerWithTitle:nil 
                         message:message 
                  preferredStyle:UIAlertControllerStyleAlert];
    
    UIViewController *rootViewController = 
        [UIApplication sharedApplication].delegate.window.rootViewController;
    [rootViewController presentViewController:alert animated:YES completion:nil];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), 
                   dispatch_get_main_queue(), ^{
        [alert dismissViewControllerAnimated:YES completion:nil];
    });
    
    result(@YES);
  } else {
    result(FlutterMethodNotImplemented);
  }
}
@end

三、配置pubspec.yaml

yaml 复制代码
name: my_flutter_plugin
description: 一个简单的Flutter插件示例,显示Toast和获取平台版本
version: 1.0.0
homepage: https://github.com/yourusername/my_flutter_plugin
repository: https://github.com/yourusername/my_flutter_plugin.git

environment:
  sdk: ">=2.19.0 <4.0.0"
  flutter: ">=3.7.0"

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0

flutter:
  plugin:
    platforms:
      android:
        package: com.example.my_flutter_plugin
        pluginClass: MyFlutterPlugin
      ios:
        pluginClass: MyFlutterPlugin

四、编写示例项目

  1. 修改 example/lib/main.dart
dart 复制代码
import 'package:flutter/material.dart';
import 'package:my_flutter_plugin/my_flutter_plugin.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  Future<void> initPlatformState() async {
    String platformVersion;
    try {
      platformVersion = await MyFlutterPlugin.getPlatformVersion();
    } catch (e) {
      platformVersion = 'Failed to get platform version.';
    }

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin Example App'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('平台版本: $_platformVersion\n'),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  MyFlutterPlugin.showToast('Hello from Flutter!');
                },
                child: Text('显示Toast'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
  1. 运行测试
bash 复制代码
cd example
flutter run

五、发布前检查

  1. 更新README.md
markdown 复制代码
# My Flutter Plugin

一个简单的Flutter插件,用于显示Toast和获取平台版本。

## 功能
- 获取当前设备平台版本
- 显示原生Toast/Alert提示

## 安装
在 `pubspec.yaml` 中添加:
```yaml
dependencies:
  my_flutter_plugin: ^1.0.0

使用示例

dart 复制代码
import 'package:my_flutter_plugin/my_flutter_plugin.dart';

// 获取平台版本
String version = await MyFlutterPlugin.getPlatformVersion();

// 显示Toast
await MyFlutterPlugin.showToast('Hello World!');
复制代码
### 2. 添加LICENSE文件
在项目根目录创建 `LICENSE` 文件(建议使用MIT许可证)

### 3. 代码格式检查
```bash
flutter analyze
dart format .

六、发布到pub.dev

  1. 注册pub.dev账号

· 访问 https://pub.dev

· 使用Google账号登录

· 获取API Token

  1. 本地登录
bash 复制代码
# 在终端登录
dart pub login
  1. 预发布检查
bash 复制代码
# 检查是否有错误
flutter pub publish --dry-run
  1. 正式发布
bash 复制代码
# 发布插件
flutter pub publish

发布过程:

  1. 终端会显示验证信息
  2. 打开浏览器确认
  3. 等待上传完成
  4. 收到确认邮件

七、发布后操作

  1. 验证发布

访问:https://pub.dev/packages/my_flutter_plugin

  1. 更新版本

修改 pubspec.yaml 中的版本号:

yaml 复制代码
version: 1.0.1  # 小版本更新
version: 1.1.0  # 功能更新  
version: 2.0.0  # 大版本更新

重新发布:

bash 复制代码
flutter pub publish
  1. 标记不推荐使用(如需弃用)
bash 复制代码
dart pub deactivate my_flutter_plugin

八、常见问题解决

  1. 发布失败:403错误

· 检查是否已登录:dart pub login

· 确认包名是否已存在

· 检查网络连接

  1. 版本冲突

· 确保每次发布版本号递增

· 使用语义化版本控制:主版本.次版本.修订号

  1. 插件无法导入

· 发布后等待5-10分钟同步

· 清理Flutter缓存:flutter clean

  1. 平台特定错误
bash 复制代码
# 重新生成iOS文件
cd example/ios
pod install

# 重新生成Android文件
flutter clean
flutter pub get

九、最佳实践

  1. 命名规范
    · 包名:小写字母+下划线
    · 方法名:清晰易懂的动词
    · 版本号:遵循语义化版本

  2. 文档完善
    · 提供完整的使用示例
    · 添加API文档注释
    · 说明平台限制

  3. 测试覆盖

    bash 复制代码
    # 运行测试
    flutter test
  4. 持续维护
    · 及时回复issue
    · 定期更新依赖
    · 保持向后兼容

十、总结

发布Flutter插件只需简单几步:

  1. 创建插件项目
  2. 编写平台代码
  3. 配置pubspec.yaml
  4. 测试示例项目
  5. 发布到pub.dev

现在你已经成功发布了自己的Flutter插件!

相关推荐
yuanlaile10 小时前
2026年全新Flutter 跨平台开发全栈学习资料整理
flutter·getx·鸿蒙 next·flutter开发鸿蒙·flutter入门实战·flutter全栈
恋猫de小郭21 小时前
Genkit Dart 1.0 发布,Flutter 原生的 AI Agent 终于完整了
android·前端·flutter
第10086个小白21 小时前
flutter桌面端打包方式(Inno Setup Compiler)版本
前端·flutter
陆断枫2 天前
Flutter 3.47 动画引擎盘点:Impeller 全平台,和那些"新特性"
flutter
程序员老刘2 天前
Flet 1.0 思路很好,可惜来晚了
flutter·ai编程·客户端
m0_738185822 天前
Flutter 鸿蒙化实战:qr_code_scanner_plus 适配 OpenHarmony,二维码扫描
flutter·华为·harmonyos·鸿蒙
恋猫de小郭2 天前
Flutter + EmbeddingGemma 2,谷歌发布完全端侧的 AI Edge Foresight
android·前端·flutter
君赏2 天前
基于 FlutterPatch 快速接入 Flutter 热更新
flutter
律宏阔3 天前
Dart FFI 内存管理:用 using + Arena 替代嵌套 try-finally
前端·flutter
律宏阔3 天前
Flutter 调用 Go:从 c-shared + ffigen 到 @Native + Native Assets 踩坑记录
前端·flutter