在编写Flutter插件时,涉及到结果回调、进度回调的时候。可以选择使用PlatformChannel、BlockCallback或FlutterEventChannel。下面简单说一下他们的使用场景。
1、PlatformChannel
PlatformChannel
是Flutter与原生平台之间通信的桥梁。通过PlatformChannel,Flutter应用程序
可以调用原生平台
的API,同时原生平台也可以向Flutter应用程序发送消息。在数据回调场景中,可以使用PlatformChannel
的registerMethodCallBack
方法来注册一个回调函数,当在原生平台调用特定方法时,会触发这个回调函数。使用PlatformChannel需要手动处理原生平台和Flutter之间的数据转换。
优点:可以调用原生平台的任意方法,通信方式多样,包括异步和同步。
缺点:需要手动处理数据转换和回调,代码比较繁琐。
2、FlutterEventChannel
FlutterEventChannel
是一种专门用于事件流处理
的方式。它使用Flutter的Stream架构,可以通过Stream将数据从原生平台
发送到Flutter应用程序
。在Flutter插件中,可以使用FlutterEventChannel来定义事件流接口,原生平台通过这个接口向Flutter应用程序发送事件。
优点:支持异步事件流处理,不需要手动处理数据转换和回调,可以使用Dart的Stream处理库进行数据处理和转换。
缺点:需要熟悉Flutter的Stream架构和使用方式。
3、BlockCallback
BlockCallback
是一种简单的回调方式,使用函数作为回调参数。在Flutter插件中,可以使用BlockCallback来定义原生平台需要调用的方法。这个方法的参数和返回值都是原生平台的类型,可以在Flutter应用程序中直接使用。
优点:使用简单,不需要手动处理数据转换和回调。
缺点:只能使用同步的方式进行通信,不适合处理大量数据或需要异步处理的情况。
4、总结
综上所述,PlatformChannel
适用于需要调用原生平台任意方法的情况,可以使用异步或同步的方式进行通信;BlockCallback
适用于简单的情况,使用同步方式进行通信;FlutterEventChannel
适用于需要处理大量数据或需要异步处理的情况,使用异步事件流进行处理。根据具体需求选择合适的方式。
5、FlutterEventChannel的使用(Object_C版)
在插件的registerWithRegistrar
方法中添加通道,如下:
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
// 方法回调
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:@"DemoPlugin"
binaryMessenger:[registrar messenger]];
// 通道1
FlutterEventChannel *eventChannel1 = [FlutterEventChannel
eventChannelWithName:"eventChannel1"
binaryMessenger:[registrar messenger]];
// 通道2
FlutterEventChannel *eventChannel2 = [FlutterEventChannel
eventChannelWithName:"eventChannel2"
binaryMessenger:[registrar messenger]];
// 通道3
FlutterEventChannel *eventChannel3 = [FlutterEventChannel
eventChannelWithName:"eventChannel3"
binaryMessenger:[registrar messenger]];
DemoPlugin *instance = [[DemoPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
[eventChannel1 setStreamHandler:instance];
[eventChannel2 setStreamHandler:instance];
[eventChannel3 setStreamHandler:instance];
}
当Flutter
端创建、销毁通道时,会自动进入iOS
下面的代理:
// flutter创建通道/开启通道
- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events {
NSString *channelName = [NSString stringWithFormat:@"%@", arguments];
if([channelName isEqualToString:@"eventChannel1"]){
self.eventSink1 = events;
}else if([channelName isEqualToString:2"eventChannel2"]){
self.eventSink2 = events;
}else if([channelName isEqualToString:@"eventChannel3"]){
self.eventSink3 = events;
}
return nil;
}
// flutter关闭通道/销毁通道
- (FlutterError *)onCancelWithArguments:(id)arguments {
NSString *channelName = [NSString stringWithFormat:@"%@", arguments];
if([channelName isEqualToString:@"eventChannel1"]){
self.eventSink1 = nil;
}else if([channelName isEqualToString:2"eventChannel2"]){
self.eventSink2 = nil;
}else if([channelName isEqualToString:@"eventChannel3"]){
self.eventSink3 = nil;
}
return nil;
}
回传演示:
if(self.eventSink1 != nil){
self.eventSink1("demo1");
}
到此,iOS端所有的工作完成。
6、FlutterEventChannel的使用(flutter版)
6.1、创建通道
// 创建一个事件通道
EventChannel eventChannel1 = EventChannel('eventChannel1');
6.2、开启通道,即开始监听回传的信息
调用下面的方法,iOS端会自动触发onListenWithArguments
的代理,完成通道开启。这里需要给receiveBroadcastStream()
加一个参数,用于区分当前通道是哪一个。
// 监听来自原生端的事件流
late StreamSubscription streamSubscription1 = = eventChannel1.receiveBroadcastStream("eventChannel1").listen((event) {
});;
这里需要说明下,为什么创建通道使用了'eventChannel1'
,监听事件流又使用到了'eventChannel1'
。
1、6.1中的是
'eventChannel1'
完成了通道的创建,需要和插件中的通道名一致。2、6.2中的是
'eventChannel1'
是事件流的监听,因为存在多个通道,iOS端在接收到onListenWithArguments
回调时,无法知道创建的是哪一个通道,所以需要在receiveBroadcastStream("eventChannel1")
这里再重新写一遍'eventChannel1'
,这样iOS就能判断出当前是哪一个通道在工作/关闭。
当然事件流这里的参数也可以换一个名称,和通道名区分开,看自己喜好。
6.3关闭通道
调用下面的方法,iOS端会自动触发onCancelWithArguments
的代理,完成通道的销毁。
streamSubscription1.cancel();