创建Flutter Pigeon插件,与iOS,Android,HarmonyOS三端通行

图片[1]-创建Flutter Pigeon插件,与iOS,Android,HarmonyOS三端通行

本文将介绍如何使用 Pigeon 开发一个 Flutter 插件,该插件用于跨端通信,能在 Flutter 和原生代码之间交换数据。

什么是 Pigeon?

Pigeon 是一个用于生成 Platform Channel 代码的工具。它基于 Dart 的类型系统,允许你定义一个接口,并自动生成对应的 Dart 和原生代码。这些生成的代码可以帮助你避免手动编写平台通道的代码,从而减少错误并提高开发效率。

Pigeon 的工作流程

  1. 定义接口:你在 Dart 中定义一个接口,指定你希望 Flutter 与原生代码之间交互的数据和方法。
  2. 生成代码:通过运行 Pigeon 工具,它将自动为你生成 Dart 代码和原生代码(Android 和 iOS)。
  3. 使用生成的代码:在 Flutter 项目中调用生成的 Dart 代码,确保你可以与原生端安全、稳定地进行通信。

步骤一:创建一个新的 Flutter 插件,进入插件目录:

flutter create --template=plugin flutter_cross_platform_communication
cd flutter_cross_platform_communication

步骤二:定义 Pigeon 接口

lib/flutter_cross_platform_communication.pigeon.dart 文件中,我们定义一个 Message 类来表示数据结构,接着定义一个接口 CommunicationApi 来处理数据交换。

  • @HostApi() 是 Pigeon 用于标记 Dart 端 API 的注解。
  • Message 类是我们要传递的数据结构,它包含了两个字段:content 和 timestamp
import 'package:pigeon/pigeon.dart';

// 定义通信数据结构
class Message {
  String? content;
  int? timestamp;
}

// 定义接口
@HostApi()
abstract class CommunicationApi {
  Message? sendMessage(String message);
}

步骤三:生成平台代码

在Flutter项目中 pubspec.yaml 文件中添加 Pigeon 的依赖项,然后运行flutter pub get

dev_dependencies:
  pigeon: ^1.0.0

生成代码

flutter pub run pigeon --input lib/flutter_cross_platform_communication.pigeon.dart --dart_out lib/flutter_cross_platform_communication_api.dart --java_out ./android/src/main/java/com/example/fluttercrossplatformcommunication/CommunicationApi.java --objc_header_out ./ios/Classes/CommunicationApi.h --objc_source_out ./ios/Classes/CommunicationApi.m

步骤四:实现原生代码

Android 实现
android/src/main/java/com/example/fluttercrossplatformcommunication/CommunicationApi.java 中实现 CommunicationApi 接口。

package com.example.fluttercrossplatformcommunication;

import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

import java.util.HashMap;
import java.util.Map;

public class CommunicationApi implements MethodCallHandler {

    private final MethodChannel channel;

    public CommunicationApi(BinaryMessenger messenger) {
        channel = new MethodChannel(messenger, "com.example.fluttercrossplatformcommunication");
        channel.setMethodCallHandler(this);
    }

    @Override
    public void onMethodCall(MethodCall call, Result result) {
        if (call.method.equals("sendMessage")) {
            String message = call.argument("message");
            long timestamp = System.currentTimeMillis();

            Map<String, Object> response = new HashMap<>();
            response.put("content", message);
            response.put("timestamp", timestamp);

            result.success(response);
        } else {
            result.notImplemented();
        }
    }
}

iOS 实现
ios/Classes/CommunicationApi.m 中实现 CommunicationApi 接口。

#import "CommunicationApi.h"
#import <Flutter/Flutter.h>

@implementation CommunicationApi

- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger {
    if (self = [super init]) {
        _channel = [FlutterMethodChannel methodChannelWithName:@"com.example.fluttercrossplatformcommunication" binaryMessenger:binaryMessenger];
        [_channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
            if ([call.method isEqualToString:@"sendMessage"]) {
                NSString *message = call.arguments[@"message"];
                NSInteger timestamp = (NSInteger)[[NSDate date] timeIntervalSince1970];

                NSDictionary *response = @{@"content": message, @"timestamp": @(timestamp)};
                result(response);
            } else {
                result(FlutterMethodNotImplemented);
            }
        }];
    }
    return self;
}

@end

步骤五:使用插件

在 Flutter 中调用 sendMessage 方法并处理返回的 Message 数据。

import 'package:flutter/services.dart';
import 'flutter_cross_platform_communication_api.dart';

class CrossPlatformCommunication {
  static const CommunicationApi _api = CommunicationApi();

  Future<Message> sendMessage(String message) async {
    try {
      final result = await _api.sendMessage(message);
      return result!;
    } on PlatformException catch (e) {
      throw Exception("Failed to send message: ${e.message}");
    }
  }
}

在 Flutter 应用中使用该插件:

import 'package:flutter/material.dart';
import 'cross_platform_communication.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final CrossPlatformCommunication _communication = CrossPlatformCommunication();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Flutter Cross-Platform Communication')),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              final message = await _communication.sendMessage('Hello from Flutter');
              print('Received: ${message.content} at ${message.timestamp}');
            },
            child: Text('Send Message'),
          ),
        ),
      ),
    );
  }
}
© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容