网易首页 > 网易号 > 正文 申请入驻

Flutter Platform Channel深度解析

0
分享至

一、简介

Platform Channel 是 Flutter 端与 Platform 端制定的通信机制,由官方提供用于 Dart 和平台之间的相互通信。

分为以下 3 种

(1)BaseMessageChannel :用于传递字符串和半结构化的信息(在大内存数据块传递的情况下使用)

(2)MethodChannel:用于传递方法调用(Method Invocation)

(3)EventChannel: 用于数据流(Event Streams)的通信

二、消息传递与编码器

Flutter 的消息传递工具是 BinaryMessager ,通过它与 Platform 建立起通信关系,消息以二进制的格式进行传递。

如图所示 BinaryMessager 的传递需要经过 BinaryMessageHandler,BinaryMessagerHandler 是以 Channel Name 作为键值生成出来再被注册到 BinaryMessager 上的,BinaryMessageHandler 和 BinaryMessager 是一一对应的,二进制格式的消息通过消息编码器(Codec)解码为可识别的信息,并传递给 Handler 进行处理。Handler 处理完后,会把结果编码为二进制格式,再通过回调函数返回结果并发送回 Flutter 端。

1.编码器分类

(1)MessageCodec:BinaryCodec、StringCodec、JSONMessageCodec、StandardMessageCodec

(2)MethodCodec:JSONMethodCodec、StandardMessageCodec

经过消息编码器处理后,消息就可以被 Handler 进行处理了。

2.消息编码过程

Android 端的返回值是 java.lang.Integer 类型的,而 iOS 端返回值则是一个 NSNumber 类型的(通过 NSNumber numberWithInt:获取)。而到了 Flutter 端时,这个返回值自动“变成 ”了 Dart 语言的 Int 类型。

standard platform channels 使用 standard messsage codec 对 message 和 response 进行序列化和反序列化,message与 response 可以是 booleans, numbers, Strings, byte buffers,List, Maps 等等,而序列化后得到的则是二进制格式的数据。

Flutter 默认的消息编码器是 StandardMessageCodec ,支持的数据类型如下:

三、MethodChannel

MethodChannel 是 Flutter 与 Platform 之间传递信息的一种,其传递过程是:BinaryMessager > BinaryMessagerHandler > MethodChannel。

如上图:Native 端(iOS 和 Android)为宿主端(host),Flutter 则是客户端(client),Flutter 调用 Native 方法时,需要传递的信息是通过平台通道传递到宿主端的,Native 收到调用的信息后方可执行指定的操作。如有返回的数据,则 Native 会将数据再通过平台通道一并传递给 Flutter,其中数据传递是异步的,这样就能确保消息传递时用户界面不会被阻塞。

1.Flutter 层(Dart 层)

Flutter 端使用 MethodChannel 的 invokeMethod 方法发起一次方法调用时,开始了消息传递流程。invokeMethod 方法会将其入参 message 和 arguments 封装成一个 MethodCall 对象,并使用 MethodCodec 将其编码为二进制格式数据,再通过 BinaryMessages 将消息发出。(注意,此处提到的类名与方法名均为 Dart 层的实现)

上述过程最终会调用到 ui.Window 的 _sendPlatformMessage 方法,该方法是一个Native 方法,其实现在 Native 层,这与 Java 的 JNI 技术非常类似。我们向 Native 层发送了三个参数:

• name,String 类型,代表 Channel 名称

• data,ByteData 类型,即之前封装的二进制数据

• callback,Function 类型,用于结果回调

2.Native 层

到 Native 层后,window.cc 的 SendPlatformMessage 方法接受了来自 Dart 层的三个参数,并对它们做了一定的处理:Dart 层的回调 callback 封装为 Native 层的 PlatformMessageResponseDart 类型的 response;dart 层的二进制数据 data 转化为 std::vector

类型数据 data;根据 response, data 以及 Channel 名称 name 创建一个 PlatformMessage 对象,并通过dartstate->window()->client()->HandlePlatformMessage 方法处理 PlatformMessage 对象。

dart_state->window()->client()是一个 WindowClient,而其具体的实现为 RuntimeController,RuntimeController 会将消息交给其代理 RuntimeDelegate 处理。

RuntimeDelegate 的实现为 Engine,Engine 在处理 Message 时,会判断该消息是否是为了获取资源(channel 等于"flutter/assets"),如果是,则走获取资源逻辑,否则调用 Engine::Delegate 的 OnEngineHandlePlatformMessage 方法。

Engine::Delegate 的具体实现为 Shell,其 OnEngineHandlePlatformMessage 接收到消息后,会向 PlatformTaskRunner 添加一个 Task,该 Task 会调用 PlatformView 的 HandlePlatformMessage 方法。值得注意的是,Task 中的代码执行在 Platform Task Runner 中,而之前的代码均执行在 UI Task Runner 中。

四、消息处理

PlatformView 的 HandlePlatformMessage 方法在不同平台有不同的实现,但是其基本原理是相同的。

1.PlatformView

AndroidPlatformViewAndroid 是 Platformview 的子类,也是其在 Android 端的具体实现。当 PlatformViewAndroid 接收到 PlatformMessage 类型的消息时,如果消息中有 response(类型为 PlatformMessageResponseDart),则生成一个自增长的 responseid,并以 responseid 为key,response 为 value 存入字典 pendingresponses 中。接着,将 channel 和 data 均转化为 Java 可识别的数据,通过 JNI 向 Java 层发起调用,将 response_id、channel 和 data 传递过去。

Java 层中,被调用的代码为 FlutterNativeView (BinaryMessager 的具体实现)的 handlePlatformMessage ,该方法会根据 channel 找到对应的 BinaryMessageHandler 并将消息传递给它处理。

BinaryMessageHandler 处理完成后,FlutterNativeView 会通过 JNI 调用 native 的方法,将 responsedata 和 responseid 传递到 native 层。

Native 层,PlatformViewAndroid 的 InvokePlatformMessageResponseCallback 接收到了 respondid 和 responsedata。其先将 responsedata 转化为二进制结果,并根据 responseid,从 pandingresponses 中找到对应的 PlatformMessageResponseDart 对象,调用其 Complete 方法将二进制结果返回。

2.PlatformViewIOS

PlatformViewIOS 是 PlatformView 的子类,也是其在 iOS 端的具体实现,当 PlatformViewIOS 接收到 message 时会交给 PlatformMessageRouter 处理。

PlatformMessageRouter通过 PlatformMessage 中的 channel 找到对应的 FlutterBinaryMessageHandler,并将二进制消息其处理,消息处理完成后,直接调用 PlatformMessage 对象中的 PlatformMessageResponseDart 对象的 Complete 方法将二进制结果返回。

3.结果回传

PlatformMessageResponseDart 的 Complete 方法向 UI Task Runner 添加了一个新的 Task,这个 Task 的作用是将二进制结果从 native 的二进制数据类型转化为 Dart 的二进制数据类型 response,并调用 Dart 的 callback 将 response 传递到 Dart 层。

Dart 层接收到二进制数据后,使用 MethodCodec 将数据解码,并返回给业务层。至此,一次从 Flutter 发起的方法调用就完整结束了。

五、具体使用

1.Flutter 端调用 Android 方法

2.Android 端代码

(1)继承 MethodCallHandler 并设置 Handler ,MethodChannel 需要保存在对象一会调用回调时需要使用,onMethodCall 为 Flutter 层回调的方法这边用 RCIMFlutterWrapper 承接处理。

(2)RCIMFlutterWrapper 类中处理, MethodCall 的 Method,对应 Flutter 层调用 invokeMethod 方法的传入的第一个参数,两端需完全对应一致。

(3)直接通过 result 对象回调回去,这样就能将结果回调。

3.关于 Android 回调 Flutter 的使用

(1)Flutter 端回调监听,设置监听 Key 两端对应。

(2)Android 端代码回调,mChannel.invokeMethod 方法将数据回调给 Flutter 层。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
骑士为何三连鞭惨败尼克斯 赛后哈登毫不避讳说出原因 说非常实在

骑士为何三连鞭惨败尼克斯 赛后哈登毫不避讳说出原因 说非常实在

小青年渌渌
2026-05-24 12:00:14
再就业!雷霆邀深圳外援巴吉打NBA夏联 战广厦曾轰14+15+6帽

再就业!雷霆邀深圳外援巴吉打NBA夏联 战广厦曾轰14+15+6帽

醉卧浮生
2026-05-24 12:54:55
7课题经费4303万!被耿同学第一枪瞄准:同济王平院长有多牛?

7课题经费4303万!被耿同学第一枪瞄准:同济王平院长有多牛?

大江看潮
2026-05-22 15:13:03
41岁C罗率队夺得沙特联冠军,将获3300万美元巨额奖金

41岁C罗率队夺得沙特联冠军,将获3300万美元巨额奖金

星耀国际足坛
2026-05-23 21:49:27
《主角》6位美女颜值排名,王晓晨第5,王丽坤第4,第1没有悬念

《主角》6位美女颜值排名,王晓晨第5,王丽坤第4,第1没有悬念

娱君坠星河
2026-05-23 16:30:09
中国准时兑现承诺,商务部:200架波音落地,向美换回三大好处!

中国准时兑现承诺,商务部:200架波音落地,向美换回三大好处!

混沌录
2026-05-22 19:17:05
姚明坐ES9出行?亚洲巨人的难题解决了

姚明坐ES9出行?亚洲巨人的难题解决了

热点科技
2026-05-24 15:01:56
媒体称美伊下一轮会谈可能在6月5日举行

媒体称美伊下一轮会谈可能在6月5日举行

界面新闻
2026-05-24 16:37:04
1970年刘伯承定居南京,许世友发现一奇事交代肖永银:你常去看看

1970年刘伯承定居南京,许世友发现一奇事交代肖永银:你常去看看

浩渺青史
2026-05-23 19:36:45
股价低至2元,牛散张素芬加仓,摩根新进,逆势暴跌37%全被套牢

股价低至2元,牛散张素芬加仓,摩根新进,逆势暴跌37%全被套牢

鹏哥投研
2026-05-24 11:38:03
首战告捷!王欣瑜晋级法网女单次轮

首战告捷!王欣瑜晋级法网女单次轮

北青网-北京青年报
2026-05-24 19:58:07
金溥聪要求更正威胁提告,中时发声明反击绝不更正!

金溥聪要求更正威胁提告,中时发声明反击绝不更正!

故事终将光明磊落
2026-05-24 11:59:20
印度失算了,中国特高压花了千亿的技术,印度拿来主义学不会

印度失算了,中国特高压花了千亿的技术,印度拿来主义学不会

史智文道
2026-04-13 10:04:19
面对大批农民饿死,他竟说:他们故意饿死自己,好让我下不了台

面对大批农民饿死,他竟说:他们故意饿死自己,好让我下不了台

山间听雨
2026-05-22 17:46:37
卡纳瓦罗:意大利人已不懂得拼搏;法国和葡萄牙是世界杯热门

卡纳瓦罗:意大利人已不懂得拼搏;法国和葡萄牙是世界杯热门

懂球帝
2026-05-24 08:18:08
女排传奇孙晋芳:退役后享正厅级待遇,66岁患血癌,靠换血续命

女排传奇孙晋芳:退役后享正厅级待遇,66岁患血癌,靠换血续命

拳击时空
2026-05-24 05:54:53
比塞克:落选国家队?我已经拼尽全力,希望欧洲杯能得到征召

比塞克:落选国家队?我已经拼尽全力,希望欧洲杯能得到征召

懂球帝
2026-05-24 02:41:06
有望获得诺贝尔生理学奖的大发现:网民中的猪悟能综合征

有望获得诺贝尔生理学奖的大发现:网民中的猪悟能综合征

熊太行
2026-05-23 15:08:14
人老了,只剩一个人的时候,千万要记住:1、不要再找老伴儿…

人老了,只剩一个人的时候,千万要记住:1、不要再找老伴儿…

富书
2026-04-30 23:20:06
美媒:爱德华兹很渴望欧文加盟森林狼,火箭也在积极引进欧文

美媒:爱德华兹很渴望欧文加盟森林狼,火箭也在积极引进欧文

懂球帝
2026-05-24 02:20:41
2026-05-24 20:28:49
融云全球智能通信云
融云全球智能通信云
专业、简单、稳定的全球互联网通信云服务商
444文章数 25关注度
往期回顾 全部

科技要闻

我戴着摄像头上班,正在帮AI抢走我饭碗

头条要闻

山西矿难遇难者家属:父亲年过半百 我们一直劝他别干了

头条要闻

山西矿难遇难者家属:父亲年过半百 我们一直劝他别干了

体育要闻

唐斯发牌,大头逆袭:骑士跌向残忍夏季

娱乐要闻

王鹤棣掉粉超20万!代言和作品遭抵制

财经要闻

爆炸致82人遇难 留神峪煤业存违法行为

汽车要闻

2027款星途瑶光上市 把"全球车"标准卷进13万级市场

态度原创

教育
房产
数码
时尚
公开课

教育要闻

西安:无人机足球点亮青少年科学梦

房产要闻

疯狂周末,海口楼市突然爆了!

数码要闻

联力调整水冷漏液保障:无法购买原产品将按当下市价全额赔付

伊姐周六热推:电视剧《嫁金枝》;电视剧《大唐迷雾 第一季》......

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版