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

news2024/11/20 7:22:04

通信原理

我们分几种场景来介绍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. 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;
  }
}

  
  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端
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端
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;
  }
}

  
  void initState() {
    // TODO: implement initState
    super.initState();
    HiFlutterBridge.getInstance();
  }
  • 运行结果
I/flutter (27181): test ===> MethodCall( sendData , Hello Flutter)
D/Native  (27181): Received back: flutter ===> native

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1011068.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

k8s集群中部署项目之流水线

微服务项目部署之流水线编写 一、部署微服务项目环境说明 1.1 代码托管到gitee 1.2 镜像托管到dockerhub 用户名&#xff1a;nextgomsb 密码&#xff1a;abc***.com1.3 流水线工具 KubeSphere 二、通过KubeSphere部署之拉取代码流水线编写 2.1 准备凭证 2.2 编辑流水线 pipe…

MySQL学习6:索引

来源 教学视频来源&#xff1a;黑马程序员 MySQL数据库入门到精通&#xff0c;从mysql安装到mysql高级、mysql优化全囊括 简介 索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构&#xff08;有序&#xff09;。在数据之外&#xff0c;数据库系统还维护着…

vue事件处理表单输入绑定

1.监听事件 我们可以使用 v-on 指令 (简写为 ) 来监听 DOM 事件&#xff0c;并在事件触发时执行对应的 JavaScript。用法&#xff1a;v-on:click"handler" 或 click"handler"。 事件处理器 (handler) 的值可以是&#xff1a; 内联事件处理器&#xff1a;事…

使用Git把项目上传到Gitee的详细步骤

1.到Git官网下载并安装 2.到Gitee官网进行注册&#xff0c;然后在Gitee中新建一个远程仓库 3.设置远程仓库的参数 4.返回Gitee查看仓库是否生成成功 5.新建一个文件夹作为你的本地仓库 6.将新建好的文件夹初始化成本地仓库 第一步&#xff1a;右键点击刚创建的本地仓库&#…

2003-2018年各省能源结构(煤炭占比)(含原始数据和计算过程)

2003-2018年各省能源结构&#xff08;煤炭占比&#xff09;&#xff08;含原始数据和计算过程&#xff09; 1、时间&#xff1a;2003-2018年 2、指标&#xff1a;原煤、洗精煤、其他洗煤、型煤、焦炭、焦炉煤气、其他煤气、其他焦化产品、原油、汽油、煤油、柴油、燃料油、液…

基于python解决鸡兔同笼问题

一、什么是鸡兔同笼问题&#xff1f; 鸡兔同笼问题是一个经典的数学问题。问题描述&#xff1a;鸡和兔子共有头数a和脚数b&#xff0c;求鸡和兔子的数量。 解析&#xff1a;设鸡的数量为x&#xff0c;兔子的数量为y&#xff0c;那么可以得到以下两个方程&#xff1a; 1. x y…

C++ PrimerPlus 复习 第二章 进入c++

第一章 命令编译链接文件 make文件 文章目录 创建C程序&#xff1b;C程序的一般格式&#xff1b;main()函数&#xff1b;使用cout对象进行输出,使用cin对象进行输入&#xff1b;coutcin #include编译指令&#xff1b;名称空间定义和使用简单函数。在C程序中加入注释&#xff1…

Nginx配置指南:如何定位、解读与优化Linux上的Nginx设置

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…

Harmony系统更改手机IP

在当今的互联网环境中&#xff0c;我们经常需要更改手机的IP地址来绕过限制或保护我们的隐私。虽然在一些操作系统上更改IP地址相对较容易&#xff0c;但在Harmony系统上&#xff0c;这可能会有些困难。因此&#xff0c;本文将分享一种在Harmony系统上免费更改手机IP地址的方法…

linux 下实现一个进度条

倒计时 理解 printf 打印的内容是被放在输出缓冲区的 fflush(stdout) 刷新 输出缓冲区&#xff1b;\n 也是一种刷新的策略我们称之为行刷新 理解一下回车换行 首先&#xff1a;回车是回车 换行是换行 回车是回到这一行的开头 换行是换到下一行 所以我们平时使用的 Enter 键 …

一线大厂Redis高并发缓存架构实战与性能优化

多级缓存架构 缓存设计 缓存穿透 缓存穿透是指查询一个根本不存在的数据&#xff0c; 缓存层和存储层都不会命中&#xff0c; 通常出于容错的考虑&#xff0c; 如果从存储层查不到数据则不写入缓存层。 缓存穿透将导致不存在的数据每次请求都要到存储层去查询&#xff0c; 失…

二叉树的概念及存储结构

目录 1.树的概念 1.1树的相关概念 1.2树的表示与应用 2.二叉树的概念及结构 2.1二叉树的概念 2.1.1特殊的二叉树 2.2.2二叉树的性质 2.2二叉树的结构 2.2.1顺序存储 2.2.2链式存储 这是一篇纯理论的博客,会对数据结构中的二叉树进行详细的讲解,让你对树的能有个清晰的…

智能语音机器人竞品调研

一、腾讯云-智能客服机器人 链接地址&#xff1a;智能客服机器人_在线智能客服_智能客服解决方案 - 腾讯云 二、阿里云-智能语音机器人 链接地址&#xff1a;智能对话机器人-阿里云帮助中心 链接地址&#xff1a;智能外呼机器人的业务架构_智能外呼机器人-阿里云帮助中心 三、火…

word文档怎么转换成pdf?几个实用文档转换方法

word文档怎么转换成pdf&#xff1f;PDF文档可以保护文档的格式和布局。如果你将Word文档发送给他人&#xff0c;他人可能会使用不同版本的Word软件打开文档&#xff0c;导致格式和布局发生变化。但是&#xff0c;如果你将Word文档转换为PDF文档&#xff0c;无论对方使用什么软件…

Android Studio的笔记--Android API的方法和位置

Android API 官网API中文API源码位置 官网API Package Index 可以修改查看对应的API等级的方法 中文API Android 包索引 源码位置 在工程的位置如下 \frameworks\base\core\java\android\ 与君共勉&#xff01;

聚观早报 | iPhone 15系列正式发布;月饼专利申请超10000项

【聚观365】9月14日消息 iPhone 15系列正式发布 月饼专利申请超10000项 “五个女博士”自建研究院 2023中国民营企业研发十强公布 华为和小米达成全球专利交叉许可协议 iPhone 15系列正式发布 2023年苹果秋季新品发布会如期而至。发布会上&#xff0c;苹果发布了iPhone 1…

visual studio code导入自定义模块(pycharm中能够运行的文件,vs code报错:未找到指定模块)

一、先看下目录结构 二、在main.py中导入Utils中的模块&#xff0c;直接导入即可 from Utils.custom_event_parse import CustomEventParse三、在custom_event_parse.py中导入execl_base.py中的模块 导入模块&#xff1a; from Utils.execl_base import ExeclBase以上这种导…

微信小程序线上加载使用iconfont问题

1.在微信小程序根目录下创建style文件夹&#xff0c;里面再创建iconfont文件夹&#xff0c;用于放置iconfont图标文件和iconfont样式文件 2.给iconfont.wxss写样式&#xff08;也可以下载iconfont代码&#xff0c;拷贝iconfont.css里的代码复制进去&#xff09; font-face {fo…

深度学习-全连接神经网络-训练过程-模型正则与超参数调优- [北邮鲁鹏]

目录标题 神经网络中的超参数学习率超参数优化方法网格搜索法随机搜索法 超参数搜索策略粗搜索精搜索 超参数的标尺空间 神经网络中的超参数 超参数 网络结构&#xff1a;隐层神经元个数&#xff0c;网络层数&#xff0c;非线性单元选择等优化相关&#xff1a;学习率、dorpou…

【绝㊙️】三年开发内功心得

经典嵌套if-else问题 这个也是老生常谈问题了&#xff0c;不管哪里都能看到。 那如何解决 方法一&#xff08;重要&#xff09;&#xff1a; 如果逻辑分支过多&#xff0c; 即使你不解决嵌套if-slse&#xff0c;至少也要把每个 if的{}里的逻辑抽到一个独立的方法或者工具类…