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的通讯。

参考