緊接着上一篇,這一篇咱們講一下原生怎麼給 Flutter 發信號,即原生-> Fluttergit
仍是經過 Flutter 官網的 Example 來說解。github
接着上一次,這一次咱們讓原生主動將電池的充電狀態發送給 Flutter 並在界面顯示。less
步驟以下。async
咱們在原先基礎上增長一列用於顯示文本。ide
String _chargingStatus = 'Battery status: unknown.'; Text(_chargingStatus),
咱們在 _BatteryWidgetState 裏面加入下面變量:ui
static const EventChannel eventChannel = EventChannel('samples.flutter.io/charging');
samples.flutter.io/charging 能夠本身指定,通常保證惟一,因此 samples 實際使用能夠替換爲包名。主要是要跟原生對應便可。this
@override void initState() { super.initState(); eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError); } void _onEvent(Object event) { setState(() { _chargingStatus = "Battery status: ${event == 'charging' ? '' : 'dis'}charging."; }); } void _onError(Object error) { setState(() { PlatformException exception = error; _chargingStatus = exception?.message ?? 'Battery status: unknown.'; }); }
能夠看到若是原生髮送 charging 顯示 charging,不然顯示 discharging。3d
固然錯誤顯示的是原生髮送過來的錯誤信息。code
注意這裏若是要獲取到錯誤信息,須要經過orm
PlatformException exception = error;
這個轉換語句才能夠。
private static final String CHARGING_CHANNEL = "samples.flutter.io/charging";
注意須要跟 Flutter 的一一對應。
new EventChannel((FlutterView) flutterView, CHARGING_CHANNEL).setStreamHandler( new EventChannel.StreamHandler() { @Override public void onListen(Object arguments, EventChannel.EventSink events) { } @Override public void onCancel(Object arguments) { } } );
具體到這裏爲:
new EventChannel((FlutterView)flutterView, CHARGING_CHANNEL).setStreamHandler( new EventChannel.StreamHandler() { private BroadcastReceiver chargingStateChangeReceiver; @Override public void onListen(Object arguments, EventChannel.EventSink events) { chargingStateChangeReceiver = createChargingStateChangeReceiver(events); registerReceiver( chargingStateChangeReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); } @Override public void onCancel(Object arguments) { unregisterReceiver(chargingStateChangeReceiver); chargingStateChangeReceiver = null; } } ); private BroadcastReceiver createChargingStateChangeReceiver(final EventChannel.EventSink events) { return new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); if (status == BatteryManager.BATTERY_STATUS_UNKNOWN) { events.error("UNAVAILABLE", "Charging status unavailable", null); } else { boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL; events.success(isCharging ? "charging" : "discharging"); } } }; }
這裏的 events.success 和 events.error 分別會調用 Flutter 的對應方法。
其中 error 的參數對應 Flutter 的 PlatformException 的參數。
PlatformException({ @required this.code, this.message, this.details, }) : assert(code != null);
這裏經過廣播的方式將電量狀態變化發送給 Flutter。
效果以下:
其實咱們點擊 Flutter 的 EventChannel,會看到源碼裏面的 receiveBroadcastStream 方法是對 MethodChannel 作了封裝。
Stream<dynamic> receiveBroadcastStream([dynamic arguments]) { final MethodChannel methodChannel = MethodChannel(name, codec); StreamController<dynamic> controller; controller = StreamController<dynamic>.broadcast(onListen: () async { BinaryMessages.setMessageHandler(name, (ByteData reply) async { if (reply == null) { controller.close(); } else { try { controller.add(codec.decodeEnvelope(reply)); } on PlatformException catch (e) { controller.addError(e); } } return null; }); try { await methodChannel.invokeMethod('listen', arguments); } catch (exception, stack) { FlutterError.reportError(FlutterErrorDetails( exception: exception, stack: stack, library: 'services library', context: 'while activating platform stream on channel $name', )); } }, onCancel: () async { BinaryMessages.setMessageHandler(name, null); try { await methodChannel.invokeMethod('cancel', arguments); } catch (exception, stack) { FlutterError.reportError(FlutterErrorDetails( exception: exception, stack: stack, library: 'services library', context: 'while de-activating platform stream on channel $name', )); } }); return controller.stream; }
因此其實原生-> Flutter 的通訊也是能夠用 MethodChannel 直接實現。
那怎麼實現呢?
欲知詳情,且聽下回講解
本文源碼位置:
https://github.com/nesger/FlutterSample/tree/feature/event_channel
https://flutter.dev/docs/development/platform-integration/platform-channels
https://github.com/flutter/flutter/tree/master/examples/platform_channel
更多閱讀:
Flutter 即學即用系列博客
Flutter 即學即用系列博客——01 環境搭建
Flutter 即學即用系列博客——02 一個純 Flutter Demo 說明
Flutter 即學即用系列博客——03 在舊有項目引入 Flutter
Flutter 即學即用系列博客——04 Flutter UI 初窺
Flutter 即學即用系列博客——05 StatelessWidget vs StatefulWidget
Flutter 即學即用系列博客——06 超實用 Widget 集錦
Flutter 即學即用系列博客——07 RenderFlex overflowed 引起的思考
Flutter 即學即用系列博客——08 MethodChannel 實現 Flutter 與原生通訊
Flutter & dart
dart 如何優雅的避空
Flutter map 妙用及 .. 使用