flutter 与原生通道封装
channel_tools.dart文件
import 'package:flutter/services.dart'; import 'dart:async'; /* * 参考文档 * 官网 https://flutter.cn/docs/development/platform-integration/platform-channels * Flutter与Native数据交互,MethodChannel https://www.jianshu.com/p/f2755c301a3e * Dart语法 http://dart.goodev.org/guides/language/language-tour * 双向通讯:https://blog.csdn.net/zl18603543572/article/details/96043692 */ /* * 通道的客户端和宿主端通过传递给通道构造函数的通道名称进行连接 * 一个应用中所使用的所有通道名称必须是唯一的 * 使用唯一的域前缀为通道名称添加前缀,比如:samples.flutter.dev/battery */ /* * Flutter 与 Android iOS 原生的通信有以下三种方式 * BasicMessageChannel 实现 Flutter 与 原生(Android 、iOS)双向通信 * MethodChannel 实现 Flutter 与 原生原生(Android 、iOS)双向通信 * EventChannel 实现 原生原生(Android 、iOS)向Flutter 发送消息 仅支持数据单向传递,无返回值。 */ //构建通道 (唯一) xxxxxx 自定义通道标识 //BasicMessageChannel const basicMessageChannel = const BasicMessageChannel( 'xxxxxx', StandardMessageCodec()); //MethodChannel const methodChannel = const MethodChannel('xxxxxx'); //EventChannel const eventChannel = const EventChannel('xxxxxx'); /* * BasicMessageChannel * 实现Flutter 调用Android iOS原生方法并回调 * arguments 发送给原生的参数 ,自定义基本数据格式{"method": "test", "content": "flutter 中的数据", "code": 100} * return数据 原生发给Flutter的参数,自定义基本数据格式{"code":100,"message":"消息","content":内容} */ Future<Map> toolsBasicChannelMethodWithParams(Map arguments) async { var result; try { result = await basicMessageChannel.send(arguments); } catch (e) { result = {'Failed': e.message}; } return result; } /* * MethodChannel * 在方法通道上调用方法invokeMethod * methodName 方法名称 * params 发送给原生的参数,自定义基本数据格式{"code":100,"message":"消息","content":内容} * return数据 原生发给Flutter的参数,自定义基本数据格式{"code":100,"message":"消息","content":内容} */ Future<Map> toolsMethodChannelMethodWithParams(String methodName, [Map params]) async { var res; try { res = await methodChannel.invokeMethod('$methodName', params); } catch (e) { res = {'Failed': e.message}; } return res; } /* * EventChannel * return数据 原生发给Flutter的参数,自定义基本数据格式{"code":100,"message":"消息","content":内容} * result listen监听结果 */ toolsEventChannelMethod(Function result) { //不指定返回值类型,函数返回值默认为Object eventChannel.receiveBroadcastStream().listen(result); }
案例文件
import 'package:flutter/material.dart'; //导入ChannelTools文件 import 'package:flutter/services.dart'; import 'package:flutter_action/Channel/channel_tools.dart'; /* * 参考文档 * https://flutter.cn/docs/development/platform-integration/platform-channels * https://www.jianshu.com/p/74c9e389e73f * https://blog.csdn.net/mcy456/article/details/96774539 * * */ class ChannelUseCasesRoute extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("MethodChannel使用案例"), actions: <Widget>[ ], ), body: ColumnWidget( ), ); } } class ColumnWidget extends StatefulWidget { @override _ColumnWidgetState createState() => _ColumnWidgetState(); } class _ColumnWidgetState extends State<ColumnWidget> { String _result = "显示接收接据"; //BasicMessageChannel 调用原生方法并回调 按钮点击触发事件 void basicChannelMethod(){ Map params = {"method":"test","context":"testValue","code": 200}; toolsBasicChannelMethodWithParams(params).then((result){ //result 原生回调结果 _result = result.toString(); print(result); }); setState(() { }); } //MethodChannel 调用原生方法并回调 按钮点击触发事件 void methodChannelMethod() { //调用ChannelTools中的方法 参数一方法名 参数二、Map类型键值对参数 toolsMethodChannelMethodWithParams('methodChannelTest').then((result){ //result 原生回调结果 _result = result.toString(); }); setState(() { }); } static const eventChannel = const EventChannel('semf.datacvg.com/eventChannel'); //EventChannel 原生数据传递 按钮点击触发事件 void eventChannelMethod(){ //data 原生 toolsEventChannelMethod((data){ _result = data; }); setState(() { }); } @override Widget build(BuildContext context) { // TODO: implement build return Center( child: Column( mainAxisAlignment:MainAxisAlignment.center, children: <Widget>[ RaisedButton.icon( icon: Icon(Icons.send), onPressed: basicChannelMethod, label: Text('BasicMessageChannel 调用原生方法并回调') ), RaisedButton.icon( icon: Icon(Icons.send), onPressed: methodChannelMethod, label: Text('MethodChannel 调用原生方法并回调') ), RaisedButton.icon( icon: Icon(Icons.send), onPressed: eventChannelMethod, label: Text('EventChannel 调用原生方法并回调') ), SizedBox( 300, child: Container( child: Text('flutter接收数据'+_result), ), ), ], ), ); } } //Toast.show("鉴权失败!", context, duration: Toast.LENGTH_LONG, gravity: Toast.CENTER); /* iOS BasicMessageChannel原生实现方法 _basicMethodChannel = [FlutterBasicMessageChannel messageChannelWithName:@"semf.datacvg.com/Test" binaryMessenger:[flutter binaryMessenger]]; // 注册方法等待flutter页面调用 [_basicMethodChannel setMessageHandler:^(id _Nullable message, FlutterReply _Nonnull callback) { NSString *method=message[@"method"]; if ([method isEqualToString:@"test"]) { //调用原生自定义方法 //[weakSelf testMethod]; //返回flutter数据 NSMutableDictionary *dic = [NSMutableDictionary dictionary]; [dic setObject:@"basicMethodChannel 原生返回flutter的数据" forKey:@"message"]; [dic setObject: [NSNumber numberWithInt:200] forKey:@"code"]; [dic setObject: @"内容" forKey:@"context"]; callback(dic); } }]; --------------- iOS MethodChannel原生实现方法 _methodChannel = [FlutterMethodChannel methodChannelWithName:@"semf.datacvg.com/semf" binaryMessenger:[flutter binaryMessenger]]; [_methodChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { NSLog(@"%@", call.method); NSLog(@"%@", call.arguments); if ([call.method isEqualToString:@"methodChannelTest"]) { //[weakSelf testMethod]; //返回flutter数据 NSMutableDictionary *dic = [NSMutableDictionary dictionary]; [dic setObject:@"methodChannel 原生返回flutter的数据" forKey:@"message"]; [dic setObject: [NSNumber numberWithInt:200] forKey:@"code"]; [dic setObject: @"内容" forKey:@"context"]; result(dic); } }]; ---------------- iOS EventChannel 原生实现方法 <FlutterStreamHandler> FlutterEventChannel* eventChannle = [FlutterEventChannel eventChannelWithName:@"semf.datacvg.com/eventChannel" binaryMessenger:[flutter binaryMessenger]]; [eventChannle setStreamHandler:self]; 数据代理 FlutterStreamHandler - (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments eventSink:(FlutterEventSink)events {}//此处的arguments可以转化为刚才receiveBroadcastStream("init")的名称,这样我们就可以一个event来监听多个方法实例 - (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments {} */