https://github.com/flutter/packages/tree/master/packages/pigeon
Pigeon是Flutter官方推荐的,用于自动生成PlatformChannel通信层模板代码(channel定义,编解码,异常处理等)的package,可以减少通信层开发时间。生成的代码通过MessageChannel进行通信。pigeon则使用MessageChannel并针对每个api方法设置唯一的channelName来进行区分,BasicMessageChannel中的T,也就是request参数和response类型都是Object,并在传输过程中对model进行编解码成Map传输。
graph LR
subgraph Pigeon/message.dart
HostApi("@HostApi")
FlutterApi("@FlutterApi")
Class("Define Class")
configurePigeon
end
subgraph server
GenerateFlutterApi
GenereateHostApi
end
subgraph client
GenerateCallHostApi
GenerateCallFullterApi
end
FlutterApi-->|handle in Flutter|GenerateFlutterApi("abstract class FlutterApi:channel.setMessageHandler and delegate to FlutterApi")
GenerateCallHostApi("class HostApi: wrap channel.send")-->|Flutter to host|HostApi
GenerateCallFullterApi("classFlutterApi: wrap channel.send")-->|host to Flutter|FlutterApi
HostApi-->|handle in host|GenereateHostApi("interface HostApi: channel.setMessageHandler and delegate to HostApi")
class NativeNetworkApi {
  Future<Resource> request(RequestParams arg) async {
    final Object encoded = arg.encode();
    const BasicMessageChannel<Object> channel =
        BasicMessageChannel<Object>('dev.flutter.pigeon.NativeNetworkApi.request', StandardMessageCodec());
    final Map<Object, Object> replyMap = await channel.send(encoded) as Map<Object, Object>;
    if (replyMap == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
        details: null,
      );
    } else if (replyMap['error'] != null) {
      final Map<Object, Object> error = (replyMap['error'] as Map<Object, Object>);
      throw PlatformException(
        code: (error['code'] as String),
        message: error['message'] as String,
        details: error['details'],
      );
    } else {
      return Resource.decode(replyMap['result']);
    }
  }
调用方式
NativeNetworkApi().request(requestParams)
/** Generated interface from Pigeon that represents a handler of messages from Flutter.*/
public interface NativeNetworkApi {
  void request(RequestParams arg, Result<Resource> result);
  /** Sets up an instance of `NativeNetworkApi` to handle messages through the `binaryMessenger`. */
  static void setup(BinaryMessenger binaryMessenger, NativeNetworkApi api) {
    {
      BasicMessageChannel<Object> channel =
          new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.NativeNetworkApi.request", new StandardMessageCodec());
      if (api != null) {
        channel.setMessageHandler((message, reply) -> {
          Map<String, Object> wrapped = new HashMap<>();
          try {
            @SuppressWarnings("ConstantConditions")
            RequestParams input = RequestParams.fromMap((Map<String, Object>)message);
            api.request(input, result -> { wrapped.put("result", result.toMap()); reply.reply(wrapped); });
          }
          catch (Error | RuntimeException exception) {
            wrapped.put("error", wrapError(exception));
            reply.reply(wrapped);
          }
        });
      } else {
        channel.setMessageHandler(null);
      }
    }
    {
配置处理方式
class NetworkPlugin : FlutterPlugin, Messages.NativeNetworkApi {
    /// The MethodChannel that will the communication between Flutter and native Android
    ///
    /// This local reference serves to register the plugin with the Flutter Engine and unregister it
    /// when the Flutter Engine is detached from the Activity
    override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        Messages.NativeNetworkApi.setup(flutterPluginBinding.binaryMessenger, this)
    }
    override fun onDetachedFromEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        Messages.NativeNetworkApi.setup(flutterPluginBinding.binaryMessenger, null)
    }
  
  override fun request(requestParams: Messages.RequestParams, result: Messages.Result<Messages.Resource>) {
    result.success(resource)
  }
Future<Resource> request(RequestParams arg) async {
sync时生成的server端handler直接代理到接口实现进行方法调用,无法异步,必须阻塞platform thread
RequestParams input = RequestParams.fromMap((Map<String, Object>)message);
Resource output = api.request(input);
wrapped.put("result", output.toMap());
reply.reply(wrapped);
async时server端handler方法签名多一个参数Result,利用回调实现异步
public interface Result<T> {
   void success(T result);
}
RequestParams input = RequestParams.fromMap((Map<String, Object>)message);
api.request(input, result -> { wrapped.put("result", result.toMap()); reply.reply(wrapped); });
https://github.com/flutter/packages/blob/master/packages/pigeon/doc
