iOS端与Flutter通信
2020-08-18 本文已影响0人
小凡凡520
一、概述
Flutter与Native之间通过Channel进行通信。消息使用Channel在客户端和主机之间传递,且Flutter中消息的传递是异步的
2942927-f532d7216f7df410.png二、三种类型的Channel
- BasicMessageChannel
于传递字符串和半结构化的消息,收到消息后可以回复消息,持续进行通信 - MethodChannel
于方法调用,是一次性通信。如Flutter调用原生相机相册等 - EventCHannel
用于数据流的通信,也是持续性通信,但收到消息后不能回复消息。通常用户原生想Flutter传递手机电量变化、网络连接变化等
三、BasicMessageChannel
/**
* @param name channel的名字.
* @param messenger 消息信使.
* @param codec 消息编解码器.
*/
+ (instancetype)messageChannelWithName:(NSString*)name
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
codec:(NSObject<FlutterMessageCodec>*)codec;
- BinaryCodec
返回值类型和入参类型均为二进制格式。实际上BinaryCodec在编解码过程中只是将二进制数据消息原封不动的返回。BinaryCodec在某些情况下非常有用,使用BinaryCodec可以使传递内存数据块时在编解码阶段免于内存拷贝 - FLutterStringCodec
用于字符串和二进制之间的编解码,编码格式为UTF-8 - FlutterJSONMessageCodec
用于基础数据和二进制数据之间的编解码,支持基础数据类型、数组、字典。iOS端使用NSJSONSerialization作为序列化工具 - FLutterBinaryCodec
是FlutterBinaryMessenger的默认编解码器,支持基础数据类型、二进制数据、数组、字典
Native端设置消息处理器接收Dart消息
// channelName 要与Dart端保持一致
static NSString *const kMessageChannelName = @"BasicMessageChannel";
- (void)initChannel {
self.messageChannel = [FlutterBasicMessageChannel messageChannelWithName:kMessageChannelName binaryMessenger:self.flutterController codec:[FlutterStringCodec sharedInstance]];
__weak typeof(self) weakSelf = self;
// 处理dart发送的消息
[self.messageChannel setMessageHandler:^(id _Nullable message, FlutterReply _Nonnull callback) {
callback([NSString stringWithFormat:@"BasicMessageChannel收到:%@",message]);
[weakSelf showMessage:message];
}];
}
Dart端发送消息给Native
//声明BasicMessageChannel
static const BasicMessageChannel<String> _basicMessageChannel= const BasicMessageChannel('messageChannelName',StringCodec());
void _sendToNative(value) async {
String response;
try{
response = await _basicMessageChannel.send('received from BasicMessageChannel');
}on PlatformException catch (e){
print(e);
}
}
Native端发送消息给Dart端并接收Dart端回复
- (IBAction)editingChanged:(id)sender {
[self.messageChannel sendMessage:self.textField.text reply:^(id _Nullable reply) {
if (reply) {
[self showMessage:reply];
}
}];
}
Dart端设置消息处理器接收Native消息并返回回复内容
@override
void initState() {
_basicMessageChannel.setMessageHandler((String message) => Future<String>((){
setState(() {
showMessage = 'BasicMessageChannel:'+message;
});
return "received message from Native:" + message;
}));
super.initState();
}
四、MethodChannel
Dart端使用MethodChannel向Native发送消息,并接受Native的回复
//创建 “ MethodChannel”这个名字要与原生创建时的传入值保持一致
static const MethodChannel _methodChannelPlugin = const MethodChannel('MethodChannel');
/*
* invokeMethod<T>(String method, [dynamic arguments])
* method:要调用的方法名
* arguments:传参
*/
response = await _methodChannelPlugin.invokeMethod('send', value);
Native端设置消息处理器接收Dart消息
static NSString *const kEventChannelName = @"EventChannel";
static NSString *const kMethodChannelName = @"MethodChannel";
- (void)initMethodChannel {
self.methodChannel = [FlutterMethodChannel methodChannelWithName:kMethodChannelName binaryMessenger:self.flutterController];
__weak typeof(HybridViewController) *weakSelf = self;
[self.methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
if ([call.method isEqualToString:@"send"]) {//调用哪个方法
result([NSString stringWithFormat:@"MethodChannel:收到Dart消息:%@",call.arguments]);
[weakSelf showMessage:[NSString stringWithFormat:@"收到Dart消息:%@ by MethodChannel",call.arguments]];
}
}];
}
五、EventChannel
Native端构造方法
/**
* @param name channel name唯一标识符与Dart端一致.
* @param messenger 消息信使.
*/
self.eventChannel = [FlutterEventChannel eventChannelWithName:kEventChannelName binaryMessenger:self.flutterController];
//设置消息处理器的代理
[self.eventChannel setStreamHandler:self];
通过下面代理方法处理消息
// FlutterEventSink:传输数据的载体
@property (nonatomic) FlutterEventSink eventSink;
#pragma mark - <FlutterStreamHandler>
//这个onListen是Flutter端开始监听这个channel时的回调,第二个参数 EventSink是用来传数据的载体
- (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments eventSink:(FlutterEventSink)eventSink {
// arguments flutter给native的参数
// 回调给flutter, 建议使用实例指向,因为该block可以使用多次
self.eventSink = eventSink;
return nil;
}
/// flutter不再接收
- (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments {
// arguments flutter给native的参数
self.eventSink = nil;
return nil;
}
Native发送消息给Dart端
- (void)sendMessageByEventChannel:(NSString *)message{
if (self.eventSink) {
self.eventSink(message);
}
}
Dart端接收Native传来的数据
// 创建 EventChannel
static const EventChannel _eventChannelPlugin = EventChannel('EventChannel');
// 初始化一个广播流从channel中接收数据,返回的Stream调用listen方法完成注册,需要在页面销毁时调用Stream的cancel方法取消监听
StreamSubscription _streamSubscription;
@override
void initState() {
_streamSubscription = _eventChannelPlugin
.receiveBroadcastStream()
.listen(_onToDart, onError: _onToDartError);
super.initState();
}
@override
void dispose() {
if (_streamSubscription != null) {
_streamSubscription.cancel();
_streamSubscription = null;
}
super.dispose();
}
void _onToDart(message) {
setState(() {
showMessage = 'EventChannel:'+message;
});
}
void _onToDartError(error) {
print(error);
}