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端
dart 复制代码
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. Flutter端
dart 复制代码
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;
  }
}
dart 复制代码
  @override
  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'),
              ),
            )
          ],
        )));
  }
  • native主动发送数据给flutter,flutter接受到消息后回信给native
    1. Android端
dart 复制代码
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. Flutter端
dart 复制代码
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;
  }
}
dart 复制代码
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    HiFlutterBridge.getInstance();
  }
  • 运行结果
dart 复制代码
I/flutter (27181): test ===> MethodCall( sendData , Hello Flutter)
D/Native  (27181): Received back: flutter ===> native
相关推荐
千里马学框架15 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台16 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone16 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc17 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo18 小时前
Kotlin 协程中的 Job 结构化并发与取消
android
sun00770019 小时前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼19 小时前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone20 小时前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen20 小时前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone20 小时前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui