Flutter 實例 - 從本地到Flutter通訊 - Event Channels

Dart4Flutter - 01 – 變量、類型和函數java

Dart4Flutter – 02 –控制流 和異常bash

Dart4Flutter – 03 – 類和泛型網絡

Dart4Flutter – 04 – 異步和庫異步

Dart4Flutter - 拾遺01 - flutter-dart環境搭建ide

Dart4Flutter - 不可變性函數

Flutter入門 - 狀態管理post

Flutter 入門實例1ui

Flutter 入門 - Container 屬性詳解google

Flutter 入門-本地訪問-MethodChannelspa

Flutter 實例 - 加載更多的ListView

Flutter 實例 - 從本地到Flutter通訊 - Event Channels

Flutter是google推出的用於移動應用開發的SDK。更多詳細信息參考官網。

Flutter應用任然須要和本地的代碼java或者Swift通訊。你任然須要本地代碼獲取移動設備硬件或者進行計算密集型操做。這個和React-Native的設計是同樣的,可是他們實現有很大的差異。

咱們不討論兩個SDK誰比較厲害。咱們只是研究一下,關於從本地代碼到Flutter通訊的問題。

Flutter的官方的文檔寫的很是好。在platform channels章節,使用大量的例子詳細說明了,經過MethodChannel和本地通訊。 可是文檔只是描述從Flutter到本地的通訊,可是沒有從本地到Flutter的通訊。

須要本地代碼的場景

實現和使用MethodChannel接口和RPC很像。從Flutter調用一個本地的方法,本地方法執行,最終以一個錯誤或者信息爲響應。這種方法調用能夠獲取當前電池的狀態、網絡狀態信息或者溫度數據。一旦本地方法作出相應,就不會再發送任何的信息,直到下次方法調用。

我對從本地到Flutter發送數據比較感興趣。這可能包括持續更新BLE或WiFi掃描結果,加速度計和陀螺儀,甚至是密集數據收集的按期狀態更新。

在搜索完java Api文檔以後,發現了EventChannel.StreamHandler能夠解決上面的問題。Dart語言也是支持Stream,他來自Akka/Monix/Rx,並且比較受歡迎的特性。

本地發送信息

添加一個針對數據流的platform channel很簡單。你須要簡單的實現StreamHandler接口,而後發射你的事件。

public class MainActivity extends FlutterActivity {
    public static final String STREAM = "com.yourcompany.eventchannelsample/stream"; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        new EventChannel(getFlutterView(), STREAM).setStreamHandler(
                new EventChannel.StreamHandler() {
                    @Override
                    public void onListen(Object args, final EventChannel.EventSink events) {
                        Log.w(TAG, "adding listener");
                    }

                    @Override
                    public void onCancel(Object args) {
                        Log.w(TAG, "cancelling listener");
                    }
                }
        );
    }
}
複製代碼

爲了保證例子大多數手機能夠運行,咱們選用RxJava庫,將時間間隔做爲事件發送出來。注意你能夠將任何的信息發送到Flutter應用。

public void onListen(Object args, EventChannel.EventSink events) {
    Log.w(TAG, "adding listener");
    timerSubscription = Observable
            .interval(0, 1, TimeUnit.SECONDS)
            .subscribe(
                    (Long timer) -> {
                        Log.w(TAG, "emitting timer event " + timer);
                        events.success(timer);// 發送事件
                    },
                    (Throwable error) -> {
                        Log.e(TAG, "error in emitting timer", error);
                        events.error("STREAM", "Error in processing observable", error.getMessage());
                    },
                    () -> Log.w(TAG, "closing the timer observable")
            );
}

@Override
public void onCancel(Object args) {
    Log.w(TAG, "cancelling listener");
    if (timerSubscription != null) {
        timerSubscription.dispose();
        timerSubscription = null;
    }
}
複製代碼

Dart 接受信息

Dart內置支持Stream,EventChannel使用Stream的功能通知什麼時候本地代碼開始發送事件和中止發送事件。爲了從本地開始發送事件,只須要給platform channel流添加監聽器。

static const stream =
    const EventChannel('com.yourcompany.eventchannelsample/stream');

StreamSubscription _timerSubscription = null;

void _enableTimer() {
  if (_timerSubscription == null) {
    _timerSubscription = stream.receiveBroadcastStream().listen(_updateTimer); // 添加監聽
  }
}

void _disableTimer() {
  if (_timerSubscription != null) {
    _timerSubscription.cancel();
    _timerSubscription = null;
  }
}
複製代碼

爲了顯示從本地來的更新次數,_updateTimer()方法這是修改_timer狀態

void _updateTimer(timer) {
  debugPrint("Timer $timer");
  setState(() => _timer = timer);
}
複製代碼

下面的log展現了,添加監聽,事件發送,事件接受,以及取消channel。

W/eventchannelsample(32641): adding listener
W/eventchannelsample(32641): emitting timer event 0
I/flutter (32641): Timer 0
W/eventchannelsample(32641): emitting timer event 1
I/flutter (32641): Timer 1
W/eventchannelsample(32641): emitting timer event 2
I/flutter (32641): Timer 2
W/eventchannelsample(32641): emitting timer event 3
I/flutter (32641): Timer 3
W/eventchannelsample(32641): emitting timer event 4
I/flutter (32641): Timer 4
W/eventchannelsample(32641): emitting timer event 5
I/flutter (32641): Timer 5
W/eventchannelsample(32641): cancelling listener
W/eventchannelsample(32641): adding listener
W/eventchannelsample(32641): emitting timer event 0
I/flutter (32641): Timer 0
W/eventchannelsample(32641): emitting timer event 1
I/flutter (32641): Timer 1
複製代碼

總結

首先回顧了從Flutter到本地的通訊方式,並且官方文檔也有詳細講解。在發現從本地到Flutter通訊的問題時,咱們發現了EventChannel,經過發送和接受事件,完成成了本地到Flutter的通訊。

參考

相關文章
相關標籤/搜索