Dart4Flutter – 01 — Variables, types, and functions
Dart4Flutter — 02 — Control flow and anomalies
Dart4Flutter — 03 — Classes and generics
Dart4Flutter — 04 — async and library
Dart 4FLUTTER – gLEANer 01 – Flutter – DART environment setup
Dart4Flutter – immutability
Flutter Entry – State management
Introduction to Flutter Example 1
Description about the properties of Flutter Container
Flutter Entry – Local access -MethodChannel
Flutter instance – Load more ListViews
Flutter instance – Local to Flutter communication – Event Channels
Flutter is Google’s SDK for mobile application development. See the official website for more details.
The Flutter application still needs to communicate with the native code Java or Swift. You still need native code to get mobile device hardware or do computationally intensive operations. This is the same design as react-Native, but their implementation is quite different.
We don’t talk about which SDK is better. We are just looking into the problem of Flutter communication from native code.
The official documentation for Flutter is very good. In the Platform Channels section, the extensive examples are used to detail local communication through method Channels. However, the documentation only describes the communication from the Flutter to the local, but not from the local to the Flutter.
Scenarios that require native code
Implementing and using the MethodChannel interface is much like RPC. A local method is invoked from Flutter. The local method executes and eventually responds with an error or message. This method call can get the current battery state, network state information, or temperature data. Once the local method responds, no more information is sent until the next method call.
I am interested in sending data from local to Flutter. This could include constant updates of BLE or WiFi scan results, accelerometers and gyroscopes, or even regular status updates with intensive data collection.
After the search the Java Api documentation, and discovered the EventChannel. StreamHandler can solve the above problems. The Dart language also supports Stream, which comes from Akka/Monix/Rx and is a popular feature.
Sending information locally
Adding a Platform channel for data flows is simple. You need to simply implement the StreamHandler interface and then emit your events.
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"); }}); }}Copy the code
To ensure that the example works on most phones, we use the RxJava library to send the time interval as an event. Note that you can send any information to the Flutter app.
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);// Send events
},
(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; }}Copy the code
Dart receives information
Dart has built-in support for Stream, which is used by EventChannel to inform local code when to start and stop sending events. To send events locally, you simply add listeners to the Platform Channel flow.
static const stream =
const EventChannel('com.yourcompany.eventchannelsample/stream');
StreamSubscription _timerSubscription = null;
void _enableTimer() {
if (_timerSubscription == null) {
_timerSubscription = stream.receiveBroadcastStream().listen(_updateTimer); // Add a listener}}void _disableTimer() {
if(_timerSubscription ! =null) {
_timerSubscription.cancel();
_timerSubscription = null; }}Copy the code
To display the number of updates from local, the _updateTimer() method modifies the _timer state
void _updateTimer(timer) {
debugPrint("Timer $timer");
setState(() => _timer = timer);
}
Copy the code
The following log shows adding listeners, sending events, receiving events, and canceling channels.
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
Copy the code
conclusion
The way to communicate from Flutter to local is first reviewed and explained in detail in the official documentation. When we discovered the problem of local to Flutter communication, we discovered EventChannel, which completes local to Flutter communication by sending and receiving events.
reference
- medium.com/@svenasse/f…