Dart4Flutter - 01 – 變量、類型和函數java
Dart4Flutter – 02 –控制流 和異常bash
Dart4Flutter - 拾遺01 - flutter-dart環境搭建ide
Flutter入門 - 狀態管理post
Flutter 入門 - Container 屬性詳解google
Flutter 入門-本地訪問-MethodChannelspa
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內置支持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的通訊。