• Flutter与Native通信原理剖析与实践


    通信原理

    我们分几种场景来介绍Flutter和Native之间的通信。

    • Native发送数据给Flutter
    • Flutter发送数据给Native
    • Flutter发送数据给Native,然后Native回传数据给Flutter

    在这里插入图片描述

    Flutter与Native通信机制

    在讲解Flutter与Native之间是如何传递数据之前,我们先了解下Flutter与Native的通信机制,Flutter和Native的通信是通过Channel来完成的。

    消息使用Channel(平台通道)在客户端(UI)和主机(平台)之间传递,如下图所示:
    在这里插入图片描述

    • Channel所支持的数据类型对照表

    在这里插入图片描述

    • Flutter定义了三种不同类型的Channel:
      1. BasicMessageChannel:用于传递字符串和半结构化的信息,持续通信,收到消息后可以回复此次消息,如:Native将遍历到的文件信息陆续传递到Flutter,在比如:Flutter将从服务端陆陆续续获取到信息交给Native加工,Native处理完返回等;
      2. MessageChannel:用于传递方法调用,一次性通信:如Flutter调用Native拍照;
      3. EventChannel:用于数据流的通信,持续通信,通常用于Native向Flutter的通信,如:手机电量变化,网络连接变化等;

    这三种类型的Channel都是全双工通信,即A<=>B,Flutter可以主动发送消息给Native端,并且Native接收到消息后可以做出回应,同样,Native端可以主动发送消息给Flutter端,Flutter端接收到数据后返回给Native。

    通信原理

    在这里插入图片描述

    • 无论是哪一种类型的Channel,它能和Flutter进行通信主要是借助BinaryMessenger来实现的。
    • 三种类型的Channel在Flutter侧都有对应的实现。

    实践

    • flutter主动发送数据给native,native接受到消息后回信给flutter
      1. Android端
    class MainActivity : FlutterActivity() {
    
        override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
            super.configureFlutterEngine(flutterEngine)
            val channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "HiFlutterBridge")//HiFlutterBridge需要和flutter端的对应
    
            channel.setMethodCallHandler { call, result ->
                Log.e("HiFlutterBridge", "argus is ${call.arguments}")
                if (call.method == "goToNative") {
                    val data = "Hello from native!"
                    result.success(data)
                } else {
                    result.notImplemented()
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. Flutter端
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/services.dart';
    
    class HiFlutterBridge {
      static HiFlutterBridge _instance = HiFlutterBridge._();
      final MethodChannel _bridge = const MethodChannel("HiFlutterBridge");//需要和原生端的MethodChannel方法的第二个参数一致
      var _listener = {};
    
      HiFlutterBridge._() {
        _bridge.setMethodCallHandler((MethodCall call) {
          String method = call.method;
          if (_listener[method] != null) {
            return _listener[method](call);
          }
          return Future(() => null);
        });
      }
    
      static HiFlutterBridge getInstance() {
        return _instance;
      }
    
      register(String method, Function(MethodCall) callBack) {
        _listener[method] = callBack;
      }
    
      unRegister(String method) {
        _listener.remove(method);
      }
    
      goToNative(Map params) async {
        String result = await _bridge.invokeMethod("goToNative", params);
        debugPrint("HiFlutterBridge result is $result");
      }
    
      MethodChannel bridge() {
        return _bridge;
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
      
      Widget build(BuildContext context) {
        // TODO: implement build
        return Scaffold(
            resizeToAvoidBottomInset: false, // 设置为false以避免在打开软键盘时widget被顶上去
            body: HideKeyboard(
                child: Stack(
              children: <Widget>[
                Align(
                  alignment: Alignment.center,
                  child: ElevatedButton(
                    onPressed: () => {
                      //flutter向native端通信
    
                      HiFlutterBridge.getInstance()
                          .goToNative({"test": "hello world"})
                    },
                    // style: ElevatedButton.styleFrom(
                    //     minimumSize: const Size(100, 50),
                    //     maximumSize: const Size(100, 50),
                    //     shape:
                    //     RoundedRectangleBorder(borderRadius: BorderRadius.circular(30))),
                    child: const Text('login'),
                  ),
                )
              ],
            )));
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • native主动发送数据给flutter,flutter接受到消息后回信给native
      1. Android端
    class MainActivity : FlutterActivity() {
    
        override fun onResume() {
            super.onResume()
            sendDataToFlutter()
        }
    
        private fun sendDataToFlutter() {
            val channel = MethodChannel(flutterEngine!!.dartExecutor.binaryMessenger, "test")
            channel.invokeMethod(" sendData ", "Hello Flutter", object : MethodChannel.Result {
                override fun success(o: Any?) {
                    Log.d("Native", "Received back: " + o.toString())
                }
    
                override fun error(s: String, s1: String?, o: Any?) {
                    Log.e("Native", "Error: $s1")
                }
    
                override fun notImplemented() {}
            })
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    1. Flutter端
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/services.dart';
    
    class HiFlutterBridge {
      static HiFlutterBridge _instance = HiFlutterBridge._();
      final MethodChannel _bridge = const MethodChannel("test");
      var _listener = {};
    
      HiFlutterBridge._() {
        _bridge.setMethodCallHandler((MethodCall call) async{
          debugPrint("test ===> ${call}");
          return "flutter ===> native";
          String method = call.method;
          if (_listener[method] != null) {
            return _listener[method](call);
          }
          return Future(() => null);
        });
      }
    
      static HiFlutterBridge getInstance() {
        return _instance;
      }
    
      register(String method, Function(MethodCall) callBack) {
        _listener[method] = callBack;
      }
    
      unRegister(String method) {
        _listener.remove(method);
      }
    
      goToNative(Map params) async {
        String result = await _bridge.invokeMethod("goToNative", params);
        debugPrint("HiFlutterBridge result is $result");
      }
    
      MethodChannel bridge() {
        return _bridge;
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
      
      void initState() {
        // TODO: implement initState
        super.initState();
        HiFlutterBridge.getInstance();
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 运行结果
    I/flutter (27181): test ===> MethodCall( sendData , Hello Flutter)
    D/Native  (27181): Received back: flutter ===> native
    
    • 1
    • 2
  • 相关阅读:
    JavaScript 用法
    Mybatis
    学生HTML游戏网页作业作品——HTML+CSS+JavaScript魔域私服游戏HTML(1个页面)
    Qt C++春晚刘谦魔术约瑟夫环问题的模拟程序
    19_数组原理内存图
    ESP32网络开发实例-TCP服务器数据传输
    云音箱服务器对接
    java集合概述
    2022 极术通讯-安谋科技“星辰”STAR-MC2处理器初探
    数据库数据恢复—SQL Server数据库ndf文件变为0KB的数据恢复案例
  • 原文地址:https://blog.csdn.net/qq_36828822/article/details/132852550