前言:在我們開發Flutter項目的時候,難免會遇到需要調用native api或者是其他的情況,這時候就需要處理Flutter與native的通信問題,一般常用的Flutter與native的通信方式有3中。
1.MethodChannel:Flutter端向native端發送通知,通常用來調用native的某一個方法。
2.EventChannel:用于資料流的通信,有監聽功能,比如電量變化後直接推送給Flutter端。
3.BasicMessageChannel:用于傳遞字元串或半結構體的資料。
接下來具體看一下每種通信方式的使用方法!
先來整體說一下邏輯思想吧,這樣能更容易了解一些,如果想要實作Flutter與native通信,首先要建立一個通信的通道,通過一個通道辨別來進行比對,比對上了之後Flutter端通過invokeMethod調用方法來發起一個請求,在native端通過onMethodCall進行比對請求的key,比對上了就處理對應case内的邏輯!!!整體來看,我感覺有點EventBus的意思呢,就像是一條事件總線。。。
第一步:實作通信插件Plugin-native端
由于一個項目中可能會需要很多Flutter與native的通信,是以我這裡是将測試的插件封裝到一個類裡面了,然後在MainActivity裡面的onCreate進行注冊
注:CHANNELNAME-->上面說過了,由于項目内會有很多的通信,是以我們定義的Channel必須是唯一的!!!!
TestPlugin實作MethodChannel.MethodCallHandler,定義一個對外暴露的注冊方法registerWith,因為我們需要在MainActivity進行注冊,在registerWith方法内初始化MethodChannel
接下來我們看一下onMethodCall方法,這個方法在Flutter發起請求時被調用,方法内有兩個參數,一個methodCall和一個result,我們分别來說一下這兩個參數:
methodCall:其中目前請求的相關資訊,比如比對請求的key
result:用于給Flutter傳回資料,有3個方法,result.success(成功調用)、result.erro(失敗調用)、result.notImplemented(方法沒有實作調用)
第二步:注冊通信插件Plugin-native端
注冊這塊我感覺作用是起到了一個橋梁的作用,通過注冊将插件和Flutter内定義的CHANNEL關聯了起來。
第三步:Flutter内發起通信請求-flutter端
這裡的功能就是頁面中央有一個text,通過點選一個按鈕,發起通信請求,通信成功在就收到native傳回的資料後将text的文案修改。
我們看一下最終的效果:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLi0zaHRGcWdUYuVzVa9GczoVdG1mWfVGc5RHLwkzX39GZhh2csATMflHLwEzX4xSZz91ZsADMx8FdsYkRGZkRG9lcvx2bjxSa2EWNhJTW1AlUxEFeVRUUfRHelRHL2EzXlpXazxyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3PnVGcq5CMjhTYhVGO2YjYmdTOhRTZjJTN4UmYmhDZkNmYlVjZ48CX0IzLcRDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL5M3Lc9CX6MHc0RHaiojIsJye.jpeg)
MethodChannel通信是雙向的,也就是說,Flutter端可以向native發起通信,native也可以向Flutter端發起通信,本質上就是反過來調用一下,原理上是同一個意思,具體的代碼就不在這裡寫了,需要的話可以自行百度一下!
EventChannel的使用我們也以官方擷取電池電量的demo為例,手機的電池狀态是不停變化的。我們要把這樣的電池狀态變化由Native及時通過EventChannel來告訴Flutter。這種情況用之前講的MethodChannel辦法是不行的,這意味着Flutter需要用輪詢的方式不停調用getBatteryLevel來擷取目前電量,顯然是不正确的做法。而用EventChannel的方式,則是将目前電池狀态"推送"給Flutter。
第一步:MainActivity内注冊EventChannel,并提供擷取電量的方法-native端
其中onCancel代表對面不再接收,這裡我們應該做一些clean up的事情。而 onListen則代表通道已經建好,Native可以發送資料了。注意onListen裡帶的EventSink這個參數,後續Native發送資料都是經過EventSink的。
第二步:同MethodChannel一樣,發起通信請求
整體說明一下:Flutter端通過stream.receiveBroadcastStream().listen監聽native發送過來的資料,native端通過eventSink.success(++count)不斷的将資料傳回給Flutter端,這樣就實作了我們想要的實時監聽的效果了!
其實他就是一個簡版的MethodChannel,也可以說MethodChannel是基于BasicMessageChannel實作的,BasicMessageChannel隻是進行通信,更通俗的了解就是兩端發通知,但是不需要進行方法比對。
第一步:初始化及注冊-native
第二步:Flutter端發起通信-flutter