preface
Following on from the last post, this post is about how primal signals a Flutter, primal -> Flutter
Again, this is explained by an Example from the Website of Flutter.
case
Then last time, this time we had the native actively send the battery charging status to Flutter and display it on the screen.
The steps are as follows.
1. Modify the Flutter interface
We add a column to display the text.
String _chargingStatus = 'Battery status: unknown.';
Text(_chargingStatus),
Copy the code
2. Flutter defines EventChannel
We add the following variables to _BatteryWidgetState:
static const EventChannel eventChannel = EventChannel('samples.flutter.io/charging');
Copy the code
Samples. The flutter. IO/charging can be specified, guarantee the only commonly, so the samples of the actual use can be replaced with the package name. Basically be to want to correspond with native can.
3. Flutter implements EventChannel listening in initState and the corresponding callback method
@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.';
});
}
Copy the code
It can be seen if native send charging displays charging, otherwise display Shipment.
Of course the error display is the native sent error message.
Note that in order to obtain the error message, you need to pass
PlatformException exception = error;
Copy the code
This conversion statement will do.
4. Define EventChannel natively
private static final String CHARGING_CHANNEL = "samples.flutter.io/charging";
Copy the code
Note that there needs to be a one-to-one correspondence with Flutter.
5. Create EventChannel natively and send content to Flutter via StreamHandler’s EventSink
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) {
}
}
);
Copy the code
Specifically, here is:
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"); }}}; }Copy the code
Here events.success and events.error call the corresponding method of Flutter, respectively.
The error argument corresponds to the PlatformException argument of the Flutter.
PlatformException({ @required this.code, this.message, this.details, }) : assert(code ! = null);Copy the code
Here changes in the state of charge are broadcast to the Flutter.
The effect is as follows:
extension
If you click on Flutter EventChannel, you will see that the receiveBroadcastStream method in the source code wraps a 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;
}
Copy the code
So native -> Flutter communication can also be implemented directly using MethodChannel.
So how do you do that?
For more details, listen to the next episode
This article source location: github.com/nesger/Flut…
Reference links:
Flutter. Dev/docs/develo… Github.com/flutter/flu…
Read more: Learn to Play with Flutter series blog – 01 Environment build with Flutter series blog – 02 A pure Flutter Demo explains the Flutter with Flutter series blog – 03 introduced in the old project StatelessWidget vs StatefulWidget Flutter Is ready to Use series blog — 06 Learning new Words & Expressions realizeStep 4 Learning New Words & Expressions realizeStep 4 Learning New Words & Expressions
How to elegantly avoid the air with a Flutter map… use