一、Flutter 中 Channel 基本概念
1. Flutter 中 Channel 的概念
- Channel 也就是通道的意思,主要是用于和 原生Native之間進(jìn)行交互 ,雙方相互傳遞數(shù)據(jù)。
- Channel 在Native的端就是一個(gè)類。
2. Flutter 中 Channel 有哪些
三種Channel之間互相獨(dú)立,各有用途,但它們?cè)谠O(shè)計(jì)上卻非常相近。
BasicMessageChannel:用于傳遞字符串和半結(jié)構(gòu)化的信息。
MethodChannel:用于傳遞方法調(diào)用(method invocation)。
EventChannel: 用于數(shù)據(jù)流(event streams)的通信(例如 NSData)。
二、Flutter 中 Channel 的詳細(xì)介紹
1. Channel 的成員變量屬性
每種Channel均有三個(gè)重要成員變量:
- name:String類型,代表Channel的名字,也是其唯一標(biāo)識(shí)符。
- messager:BinaryMessenger類型,代表消息信使,是消息的發(fā)送與接收的工具。
- codec: MessageCodec 類型 或MethodCodec類型,代表消息的編解碼器。
2. Channel 的成員變量 - name
- 一個(gè)Flutter應(yīng)用中可能存在多個(gè)Channel,每個(gè)Channel在創(chuàng)建時(shí)必須指定一個(gè)獨(dú)一無二的name,Channel之間使用 name 來區(qū)分彼此。
- 當(dāng)有消息從 Flutter端 發(fā)送到 Native端 時(shí),會(huì)根據(jù)其傳遞過來的 channel name 找到該Channel對(duì)應(yīng)的Handler(消息處理器)。
(1)Channel 的成員變量 - BinaryMessenger
BinaryMessenger是Platform端與Flutter端通信的工具,傳遞數(shù)據(jù)格式為二進(jìn)制。
當(dāng)我們初始化一個(gè)Channel,并向該Channel注冊(cè)處理消息的Handler時(shí),實(shí)際上會(huì)生成一個(gè)與之對(duì)應(yīng)的 BinaryMessageHandler ,并以 channel name 為 key,注冊(cè)到BinaryMessenger 中。
當(dāng)Flutter端發(fā)送消息到BinaryMessenger時(shí),BinaryMessenger會(huì)根據(jù)其入?yún)hannel找到對(duì)應(yīng)的BinaryMessageHandler,并交由其處理。
Binarymessenger 在 iOS 和 Android 上分別是什么?
- Binarymessenger 在Android端是一個(gè)接口,其具體實(shí)現(xiàn)為FlutterNativeView。
- 在iOS端是一個(gè)協(xié)議,名稱為FlutterBinaryMessenger,F(xiàn)lutterViewController 遵循了它。
(3) Channel 的成員變量 - codec (消息編解碼器)
- Codec主要用于將二進(jìn)制格式的數(shù)據(jù)轉(zhuǎn)化為Handler能夠識(shí)別的數(shù)據(jù)。
抽象邏輯
- (示例 StringCodec, BinaryCode, JSONMessageCodec)
如何解決數(shù)據(jù)傳遞編解碼問題?
- 由于Channel從BinaryMessageHandler接收到的消息是 二進(jìn)制格式數(shù)據(jù) ,無法直接使用,故Channel會(huì)將該二進(jìn)制消息通過Codec(消息編解碼器)解碼為能識(shí)別的消息并傳遞給Handler進(jìn)行處理。
?* 當(dāng)Handler處理完消息之后,會(huì)通過回調(diào)函數(shù)返回result,并將result通過編解碼器編碼為二進(jìn)制格式數(shù)據(jù),通過BinaryMessenger發(fā)送回Flutter端。
Codec 的介紹
Flutter定義了兩種Codec:MessageCodec 和 MethodCodec。
MessageCodec 有多種不同實(shí)現(xiàn)
-
BinaryCodec
- BinaryCodec 在編解碼過程中什么都沒做,只是原封不動(dòng)將二進(jìn)制數(shù)據(jù)消息返回而已。
- 其返回值類型和入?yún)⒌念愋拖嗤?,均為二進(jìn)制格式(Android中為ByteBuffer,iOS中為NSData)
-
StringCodec
- StringCodec 用于字符串與二進(jìn)制數(shù)據(jù)之間的編解碼,其編碼格式為UTF-8。
-
JSONMessageCodec
- JSONMessageCodec用于基礎(chǔ)數(shù)據(jù)與二進(jìn)制數(shù)據(jù)之間的編解碼,其支持基礎(chǔ)數(shù)據(jù)類型以及列表、字典。其在iOS端使用了NSJSONSerialization作為序列化的工具,而在Android端則使用了其自定義的JSONUtil與StringCodec作為序列化工具。
-
StandardMessageCodec (默認(rèn)如果不指定)
- StandardMessageCodec 是BasicMessageChannel的默認(rèn)編解碼器,其支持基礎(chǔ)數(shù)據(jù)類型、二進(jìn)制數(shù)據(jù)、列表、字典。
MethodCodec 有多種不同實(shí)現(xiàn)
- JSONMethodCodec
JSONMethodCodec的編解碼依賴于JSONMessageCodec,當(dāng)其在編碼MethodCall時(shí),會(huì)先將MethodCall轉(zhuǎn)化為字典{"method":method,"args":args}。其在編碼調(diào)用結(jié)果時(shí),會(huì)將其轉(zhuǎn)化為一個(gè)數(shù)組,調(diào)用成功為[result],調(diào)用失敗為[code,message,detail]。再使用JSONMessageCodec將字典或數(shù)組轉(zhuǎn)化為二進(jìn)制數(shù)據(jù)。
- StandardMethodCodec
MethodCodec的默認(rèn)實(shí)現(xiàn),StandardMethodCodec的編解碼依賴于StandardMessageCodec,當(dāng)其編碼MethodCall時(shí),會(huì)將method和args依次使用StandardMessageCodec編碼,寫入二進(jìn)制數(shù)據(jù)容器。其在編碼方法的調(diào)用結(jié)果時(shí),若調(diào)用成功,會(huì)先向二進(jìn)制數(shù)據(jù)容器寫入數(shù)值0(代表調(diào)用成功),再寫入StandardMessageCodec編碼后的result。而調(diào)用失敗,則先向容器寫入數(shù)據(jù)1(代表調(diào)用失?。僖来螌懭隨tandardMessageCodec編碼后的code,message和detail。
抽象邏輯圖
Flutter 中 Channel 具體實(shí)現(xiàn)
-
FlutterMethodChannel

-
FlutterBasicMessageChannel








