zoukankan      html  css  js  c++  java
  • flutter项目 通道Channel封装及使用案例

    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 {}
    
     */
  • 相关阅读:
    结构体运算符重载出错分析
    已知空间三个点,解算外接圆圆心坐标,C++编程实现
    IQueryable与IEnumberable的区别
    Asp.net MVC中关于@Html标签Label、Editor使用
    MVC 基架不支持 Entity Framework 6 或更高版本 即 NuGet的几个小技巧
    MVC下拉框Html.DropDownList 和DropDownListFor 的常用方法
    js jq封装ajax方法
    httpSession的正确理解
    vs未能解析此远程名称: 'api.nuget.org'
    未能加载文件或程序集“EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”
  • 原文地址:https://www.cnblogs.com/lulushen/p/12106300.html
Copyright © 2011-2022 走看看