当前位置: 首页 > news >正文

(原创)Flutter与Native通信的方式:EventChannel和BasicMessageChannel

前言

上一篇博客主要介绍了MethodChannel的使用方式
Flutter与Native通信的方式:MethodChannel
这篇博客接着讲另外两种通信方式
EventChannel和BasicMessageChannel

EventChannel用于从native向flutter发送通知事件,例如flutter通过其监听Android的重力感应变化等。与MethodChannel不同,EventChannel是native到flutter的单向调用,调用是多播(一对多)的,可以类比成Android的Brodcast。

BasicMessageChannel用于在flutter和native互相发送消息,一方给另一方发送消息,收到消息之后给出回复。它和MethodChannel的区别重在一个消息的回复

EventChannel

Android端调用Flutter端

首先是Flutter端代码,创建一个EventChannel并约定好字段:

static const EventChannel _channel = EventChannel('tofluttereventchannel');

然后写好被调用的方法:

  void _enableEventReceiver() {//延时3s,先让 Android 端的 EventChannel 进行初始化 , 然后在 Flutter 端注册 EventChannel 监听//这样才能确保连接成功Future.delayed(const Duration(milliseconds: 5000), () {_streamSubscription =_channel.receiveBroadcastStream().listen((dynamic event) {print('收到消息 event: $event');setState(() {mMessage = event;});}, onError: (dynamic error) {print('出现错误 error: ${error.message}');setState(() {errmMessage = error.message;});});});}

_enableEventReceiver方法可以放到Widget的initState()中初始化
在dispose()中调用以下取消监听的方法:

  void _disableEventReceiver() {if (_streamSubscription != null) {print("flutter断开连接");//断开连接,这里也会触发android端的onCancel方法_streamSubscription?.cancel();_streamSubscription = null;}}

然后来到Android端,定义两个对象
一个是EventChannel,一个是EventSink:

  private lateinit var channel: EventChannelvar eventSink: EventChannel.EventSink? = null

继续在configureFlutterEngine方法中做处理:

    channel = EventChannel(flutterEngine.dartExecutor, "tofluttereventchannel")channel.setStreamHandler(object : EventChannel.StreamHandler {override fun onListen(arguments: Any?, events: EventChannel.EventSink) {Log.d("MyFlutterActivity", "已建立连接")eventSink = events}override fun onCancel(arguments: Any?) {Log.d("MyFlutterActivity", "已断开连接")}})

可以看到,其实就是在建立连接后对EventSink对象进行赋值
当eventSink 赋值后,就可以拿他进行消息的发送了
比如:

  override fun onResume() {super.onResume()//这里延时执行是为了模拟eventSink初始化后,我们在业务里面进行消息的发送Handler().postDelayed({eventSink?.success("这是来自安卓的消息")//执行了endOfStream后,再发送消息就无效了,所以这行代码要放到endOfStream上面执行eventSink?.error("error code", "这是来自安卓的错误消息", "error details")//结束通信,这时候onCancel会被调用eventSink?.endOfStream()}, 6000)}

这样EventChannel的使用就介绍完了

注意

在实际运行时,可能会发现不起作用
归根结底是注册和调用顺序问题
所以最好在Flutter先延迟一下注册监听
让 Android 端的 EventChannel 先建立连接,
然后在 Flutter 端注册 EventChannel 监听
这样才能确保连接成功
所以用 Future.delayed 进行延时操作
具体可以参考这篇博客:
Flutter 混合开发报错

MessageChannel

MessageChannel重在回调后的消息回复
相对与其他Channel类型的创建,MessageChannel的创建除了channel名以外,还需要指定编码方式。
因为发送的消息会以二进制的形式进行处理,所以要针对不同类型的数进行二进制编码
主要方式有:
在这里插入图片描述
下面看具体使用

Flutter端

Flutter端,首先定义BasicMessageChannel

  static const messageChannel = BasicMessageChannel('tofluttemessagechannel', StringCodec());

发送消息这样写:

  ///发送MessageChannel消息,延时一下,确保安卓端先注册了监听才能收到void _sendMessage()  {Future.delayed(const Duration(milliseconds: 6000), () async {final String? result = await messageChannel.send('来自flutter主动发送的消息');print("收到安卓端的返回值:${result}");});}

可以看到发送后会拿到返回值result

注册回调,也就是接受消息这样写:

    //注册MessageChannel消息监听messageChannel.setMessageHandler((message) async {print('收到安卓端的MessageChannel消息 = $message');setState(() {forNativeMsg = message ?? "";});return '来自flutter返回的消息';});//发送MessageChannel消息

可以看到接收到后也会给到Android端一个返回值
利用BasicMessageChannel,我们就很快的完成了消息的发送和接收
并且每一个操作都可以接受或者传送返回值

Android端

Android端其实和Flutter端几乎一样
首先是定义BasicMessageChannel

    //先注册MessageChannelval messageChannel = BasicMessageChannel(flutterEngine.dartExecutor,"tofluttemessagechannel",StringCodec.INSTANCE)

发送消息:

    //发送消息Handler().postDelayed({messageChannel.send("来自安卓端主动发送的消息") { result ->Log.d("MyFlutterActivity", "收到flutter端的返回值:$result")}}, 500)

注册回调,也就是接受消息

    //先注册监听messageChannel.setMessageHandler { message, reply ->Log.d("MyFlutterActivity", "收到flutter端的MessageChannel消息:"+message)reply.reply("来自安卓端返回的消息")}

注意

这里其实也要注意一个顺序问题
总结起来就是:先注册,后发送
先让被回调的那一端注册监听完成后
再去跨端调用,也就是发送消息

总结

最后来总结一下三种方式的区别:

通信方式双端通信指定编码注册顺序使用场景
MethodChannel支持不需要延时注册方法调用
EventChannelNative单向调用Flutter先建立连接再监听广播通知
BasicMessageChannel支持先注册,再监听用于传递字符串和半结构化的消息

源码

源码地址:
EventChannel和BasicMessageChannel

相关资料

这是一份全面 & 详细的Android Native与Flutter的通信方式 学习指南

相关文章:

(原创)Flutter与Native通信的方式:EventChannel和BasicMessageChannel

前言 上一篇博客主要介绍了MethodChannel的使用方式 Flutter与Native通信的方式:MethodChannel 这篇博客接着讲另外两种通信方式 EventChannel和BasicMessageChannel EventChannel用于从native向flutter发送通知事件,例如flutter通过其监听Android的重…...

【解决】el-tree报Cannot read property ‘getCheckedKeys‘ of undefined

如果你报错 Cannot read property getCheckedKeys of undefined 或者 Cannot read property getCheckedNodes of undefined 只要在你的在<el-tree>上加个这个&#xff0c;就可以了 ref"tree"...

车载软件架构 —— 信息安全与基础软件

车载软件架构 —— 信息安全与基础软件 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他人的角度来反对自己。人生在世,最怕…...

C\C++内存管理

目录 1.C/C内存分布2.C语言中动态内存管理方式3.C中动态内存管理3.1new/delete内置类型3.2new和delete操作自定义类型 4.operator new与operator delete函数4.2重载operator new与operator delete&#xff08;了解&#xff09; 5.new和delete的实现原理5.1内置类型5.2 自定义类…...

会议室预约系统-检验是否被预约核心SQL

会议室预约时&#xff0c;判断能否被预约&#xff0c;即查询是否已经有预约记录&#xff0c;存在不能被预约。 s,e&#xff1b;表示已经预约的开始结束时间&#xff1b; ns,ne&#xff0c;表示表单提交的预约时间&#xff1b; 只需要(ns,ne)与(s,e)区间没有交集&#xff0c;可…...

C++11类模板

类模板是用来生成类的蓝图&#xff0c;与函数模板的不同之处是&#xff0c;编译器不能为类模板推断模板参数类型。 所以我们在使用类的时候要带上<>并且指定类型如下 vector<int> v; // 需要带上<int> 哦定义类模板 如下&#xff0c;和函数模板差不多都是…...

SpiderFlow爬虫平台(爬虫学习)

申明 作为自己学习的记录,方面后期查阅 官网 SpiderFlow官网 简介 spider-flow 是一个爬虫平台&#xff0c;以图形化方式定义爬虫流程&#xff0c;无需代码即可实现一个爬虫 是使用springboot开发的项目,后端代码直接运行即可使用...

Rime输入法配置

Rime输入法在我电脑上&#xff0c;删了装&#xff0c;装了删&#xff0c;已经反复好几次了。就像是Vim&#xff0c;用它的时候&#xff0c;感觉各种配置太麻烦&#xff0c;想要的功能不知道怎么实现。转用其它编辑器的时候&#xff0c;却又念着它的快捷键和可定制性&#xff0c…...

R语言学习笔记--列表list、数据框

列表 1-列表 列表可以包含不同类型的对象&#xff0c;也就是说&#xff0c;列表不是将某些具体的值组织起来&#xff0c;而是组织R对象。列表将数据组织在一个一维集合中。 列表非常好用&#xff0c;因为它可以装任何类型的对象&#xff0c;不要求数据之间是同质的。 创建列…...

电磁波定义、特性以及信道相关知识

文章目录 前言一、电磁波的定义、特性、波谱1、电磁波的特性2、电磁波谱的划分及用途 二、地球大气层的结构三、电磁波的传播方式1、地波&#xff08;ground-wave&#xff09;2、天波&#xff08;sky-wave&#xff09;3、视线传播&#xff08;line-of-sight&#xff09;①、相关…...

TCP KeepAlive与HTTP Keep-Alive

TCP KeepAlive与HTTP Keep-Alive TCP KeepAliveHTTP Keep-AliveTCP服务器怎么检测客户端断开连接 TCP KeepAlive TCP连接建立之后&#xff0c;如果应用程序或者上层协议一直不发送数据&#xff0c;或者隔很长时间才发送一次数据&#xff0c;那么TCP需要判断是应用程序掉线了还…...

SkyWalking链路追踪-Agent (代理人)

基础概念&#xff1a; SkyWalking链路追踪代理&#xff08;SkyWalking Tracing Agent&#xff09;是一种用于收集和传输链路追踪数据的工具。它与应用程序一起部署&#xff0c;并通过自动或手动方式来收集关于应用程序中的请求路径和操作的信息。该代理将收集到的数据发送到Sky…...

多线程案例 | 单例模式、阻塞队列、定时器、线程池

多线程案例 1、案例一&#xff1a;线程安全的单例模式 单例模式 单例模式是设计模式的一种 什么是设计模式&#xff1f; 设计模式好比象棋中的 “棋谱”&#xff0c;红方当头炮&#xff0c;黑方马来跳&#xff0c;针对红方的一些走法&#xff0c;黑方应招的时候有一些固定的…...

C++文件操作

1.写文件 //文件操作 #include<fstream> int main() {//写文件//路径 -- 此路径没有就生成给文件 string filePath R"(E:\项目\test.txt)";//打开文件 ios::app在后面追加内容 啥也不跟是覆盖写入ofstream fout(filePath, ios::app);//检查是否打开成功if (…...

overleaf(latex) 公式过大,需要调小字体,同时公式编号字体不变的方法

提问&#xff1a;用latex编辑的双列排版的论文中&#xff0c;如果一个包含矩阵的公式中&#xff0c;矩阵过大&#xff0c;导致超出列的范围&#xff0c;一般该如何调整呢&#xff1f; 回答&#xff1a;如果你在LaTeX中的双列排版中遇到了一个矩阵过大而导致超出列范围的问题&a…...

flink采用thrift读取tablets一个天坑

原先的配置 [INFO] StarRocksSourceBeReader [open Scan params.mem_limit 8589934592 B] [INFO] StarRocksSourceBeReader [open Scan params.query-timeout-s 600 s] [INFO] StarRocksSourceBeReader [open Scan params.keep-alive-min 100 min] [INFO] StarRocksSourceBeRea…...

Android 面试题 异常捕获 四

&#x1f525; 为什么要捕获奔溃 &#x1f525; 因为在开发或者测试阶段不能做到100%的问题解决&#xff0c;因为 app 上线之后会有你想不到的各种各样的使用的场景&#xff0c;而发生问题时用户只能描述一下怎么怎么怎么就出现了问题。也许反馈到开发这边可以100%复现那就可以…...

自动化测试:让软件测试更高效更愉快!

谈谈那些实习测试工程师应该掌握的基础知识&#xff08;一&#xff09;_什么时候才能变强的博客-CSDN博客https://blog.csdn.net/qq_17496235/article/details/131839453谈谈那些实习测试工程师应该掌握的基础知识&#xff08;二&#xff09;_什么时候才能变强的博客-CSDN博客h…...

SpringCloud学习—Feign负载均衡

Feign简介 Feign是声明式Web Service客户端&#xff0c;它让微服务之间的调用变得更简单&#xff0c;类似controller调用service。SpringCloud集成了Ribbon和Eureka&#xff0c;可以使用Feigin提供负载均衡的http客户端 只需要创建一个接口&#xff0c;然后添加注解即可。使用…...

5G时代的APP开发:机遇与挑战

APP开发是互联网行业中的重要组成部分&#xff0c;随着5G时代的到来&#xff0c;移动 APP开发也迎来了新的机遇和挑战。 5G时代不仅会为移动 APP开发带来新的发展机遇&#xff0c;也会给移动 APP开发带来新的挑战。对于企业和开发者而言&#xff0c;5G时代带来的机遇和挑战是并…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

网页端 js 读取发票里的二维码信息(图片和PDF格式)

起因 为了实现在报销流程中&#xff0c;发票不能重用的限制&#xff0c;发票上传后&#xff0c;希望能读出发票号&#xff0c;并记录发票号已用&#xff0c;下次不再可用于报销。 基于上面的需求&#xff0c;研究了OCR 的方式和读PDF的方式&#xff0c;实际是可行的&#xff…...

验证redis数据结构

一、功能验证 1.验证redis的数据结构&#xff08;如字符串、列表、哈希、集合、有序集合等&#xff09;是否按照预期工作。 2、常见的数据结构验证方法&#xff1a; ①字符串&#xff08;string&#xff09; 测试基本操作 set、get、incr、decr 验证字符串的长度和内容是否正…...

虚幻基础:角色旋转

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 移动组件使用控制器所需旋转&#xff1a;组件 使用 控制器旋转将旋转朝向运动&#xff1a;组件 使用 移动方向旋转 控制器旋转和移动旋转 缺点移动旋转&#xff1a;必须移动才能旋转&#xff0c;不移动不旋转控制器…...

代理服务器-LVS的3种模式与调度算法

作者介绍&#xff1a;简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们上一章介绍了Web服务器&#xff0c;其中以Nginx为主&#xff0c;本章我们来讲解几个代理软件&#xff1a…...

RocketMQ 客户端负载均衡机制详解及最佳实践

延伸阅读&#xff1a;&#x1f50d;「RocketMQ 中文社区」 持续更新源码解析/最佳实践&#xff0c;提供 RocketMQ 专家 AI 答疑服务 前言 本文介绍 RocketMQ 负载均衡机制&#xff0c;主要涉及负载均衡发生的时机、客户端负载均衡对消费的影响&#xff08;消息堆积/消费毛刺等…...

Windows开机自动启动中间件

WinSW&#xff08;Windows Service Wrapper 是一个开源的 Windows 服务包装器&#xff0c;它可以帮助你将应用程序打包成系统服务&#xff0c;并实现开机自启动的功能。 一、下载 WinSW 下载 WinSW-x64.exe v2.12.0 (⬇️ 更多版本下载) 和 sample-minimal.xml 二、配置 WinS…...

STM32CubeMX-H7-19-ESP8266通信(中)--单片机控制ESP8266实现TCP地址通信

前言 上篇文章我们已经能够使用串口助手实现esp8266的几种通信&#xff0c;接下来我们使用单片机控制实现。这篇文章会附带教程&#xff0c;增加.c和,.h&#xff0c;把串口和定时器放到对应的编号&#xff0c;然后调用初始化就可以使用了。 先讲解&#xff0c;然后末尾再放源码…...