flutter與原生交互方法和底層原理分析

一、flutter集成流程

1.環(huán)境準(zhǔn)備,參考鏈接
2.添加國(guó)內(nèi)環(huán)境配置:參考鏈接
3.新建

二、 iOS和android與flutter交互方式

  1. 由于在初始化flutter頁(yè)面時(shí)會(huì)傳遞一個(gè)字符串——route,因此我們就可以拿route來(lái)做文章,傳遞自己想要傳遞的數(shù)據(jù)。該種方式僅支持單向數(shù)據(jù)傳遞且數(shù)據(jù)類型只能為字符串,無(wú)返回值。
  2. 通過(guò)EventChannel來(lái)實(shí)現(xiàn),EventChannel僅支持?jǐn)?shù)據(jù)單向傳遞,無(wú)返回值,用于數(shù)據(jù)流(event streams)的通信。
  3. 通過(guò)MethodChannel來(lái)實(shí)現(xiàn),MethodChannel支持?jǐn)?shù)據(jù)雙向傳遞,有返回值,用于傳遞方法調(diào)用(method invocation)。
  4. 通過(guò)BasicMessageChannel來(lái)實(shí)現(xiàn),BasicMessageChannel支持?jǐn)?shù)據(jù)雙向傳遞,有返回值,可用于傳遞字符串和半結(jié)構(gòu)化的信息。
  5. 通過(guò)dart:ffi庫(kù)調(diào)用原生C API。

三、理解Platform Channel工作原理

1. 三種Channel均有三個(gè)重要成員變量:

name: String類型,代表Channel的名字,也是其唯一標(biāo)識(shí)符。
messager:BinaryMessenger類型,代表消息信使,是消息的發(fā)送與接收的工具。
codec: MessageCodec類型或MethodCodec類型,代表消息的編解碼器。

2. 消息信使:BinaryMessenger

image.png
  • BinaryMessenger是Platform端與Flutter端通信的工具,其通信使用的消息格式為二進(jìn)制格式數(shù)據(jù)。當(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在Android端是一個(gè)接口,其具體實(shí)現(xiàn)為FlutterNativeView。在iOS端是一個(gè)協(xié)議,名稱為FlutterBinaryMessenger,F(xiàn)lutterViewController遵循了這個(gè)協(xié)議。
  • Binarymessenger并不知道Channel的存在,它只和BinaryMessageHandler打交道。而Channel和BinaryMessageHandler則是一一對(duì)應(yīng)的。由于Channel從BinaryMessageHandler接收到的消息是二進(jìn)制格式數(shù)據(jù),無(wú)法直接使用,故Channel會(huì)將該二進(jìn)制消息通過(guò)Codec(消息編解碼器)解碼為能識(shí)別的消息并傳遞給Handler進(jìn)行處理。當(dāng)Handler處理完消息之后,會(huì)通過(guò)回調(diào)函數(shù)返回result,并將result通過(guò)編解碼器編碼為二進(jìn)制格式數(shù)據(jù),通過(guò)BinaryMessenger發(fā)送回Flutter端。

3. 消息編解碼器:Codec

image.png
3.1 MessageCodec

fluuter中的MessageCodec用于二進(jìn)制格式數(shù)據(jù)與基礎(chǔ)數(shù)據(jù)之間的編解碼。BasicMessageChannel所使用的編解碼器就是MessageCodec。
iOS中,名稱為FlutterMessageCodec,是一個(gè)協(xié)議,定義了兩個(gè)方法:encode接收一個(gè)類型為id的消息,將其編碼為NSData類型,而decode接收NSData類型消息,將其解碼為id類型數(shù)據(jù)。
MessageCodec有多種不同的實(shí)現(xiàn):

  • BinaryCodec
    BinaryCodec是最為簡(jiǎn)單的一種Codec,因?yàn)槠浞祷刂殿愋秃腿雲(yún)⒌念愋拖嗤鶠槎M(jìn)制格式(Android中為ByteBuffer,iOS中為NSData)。實(shí)際上,BinaryCodec在編解碼過(guò)程中什么都沒(méi)做,只是原封不動(dòng)將二進(jìn)制數(shù)據(jù)消息返回而已。使用BinaryCodec可以使傳遞內(nèi)存數(shù)據(jù)塊時(shí)在編解碼階段免于內(nèi)存拷貝。
  • StringCodec
    StringCodec用于字符串與二進(jìn)制數(shù)據(jù)之間的編解碼,其編碼格式為UTF-8
  • JSONMessageCodec
    JSONMessageCodec用于基礎(chǔ)數(shù)據(jù)與二進(jìn)制數(shù)據(jù)之間的編解碼,其支持基礎(chǔ)數(shù)據(jù)類型以及列表、字典。其在iOS端使用了NSJSONSerialization作為序列化的工具
  • StandardMessageCodec
    StandardMessageCodec是BasicMessageChannel的默認(rèn)編解碼器,其支持基礎(chǔ)數(shù)據(jù)類型、二進(jìn)制數(shù)據(jù)、列表、字典
3.2 MethodCodec

與MessageCodec不同的是,MethodCodec用于MethodCall對(duì)象的編解碼,一個(gè)MethodCall對(duì)象代表一次從Flutter端發(fā)起的方法調(diào)用。MethodCall有2個(gè)成員變量:String類型的method代表需要調(diào)用的方法名稱,通用類型(Android中為Object,iOS中為id)的arguments代表需要調(diào)用的方法入?yún)?br> 由于處理的是方法調(diào)用,故相比于MessageCodec,MethodCodec多了對(duì)調(diào)用結(jié)果的處理。當(dāng)方法調(diào)用成功時(shí),使用encodeSuccessEnvelope將result編碼為二進(jìn)制數(shù)據(jù),而當(dāng)方法調(diào)用失敗時(shí),則使用encodeErrorEnvelope將error的code、message、detail編碼為二進(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編碼,寫(xiě)入二進(jìn)制數(shù)據(jù)容器。其在編碼方法的調(diào)用結(jié)果時(shí),若調(diào)用成功,會(huì)先向二進(jìn)制數(shù)據(jù)容器寫(xiě)入數(shù)值0(代表調(diào)用成功),再寫(xiě)入StandardMessageCodec編碼后的result。而調(diào)用失敗,則先向容器寫(xiě)入數(shù)據(jù)1(代表調(diào)用失?。?,再依次寫(xiě)入StandardMessageCodec編碼后的code,message和detail。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容