Flutter: Simple example of passing messages between Flutter and native code
I found the example of sending messages between Flutter and native code overly complicated because it’s part of a larger tutorial that includes several different things and doesn’t explain any of the individual parts. I wanted to isolate just the message passing.
It turns out to be easier than the original tutorial implies.
The process is relatively simple. A method channel listener is set up on the receiving end. The sender then connects to the channel and sends the name of the method to execute.
Flutter to native
First set up the handler in MainActivity.java
:
//MainActivity.java
//The name of the channel that the sender and receiver are going to listen to.
private static final String CHANNEL = "com.example.app/channel";
//..snip..
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
// Register a MethodChannel listener
// This will get called when Flutter sends a message
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("methodName")) { // The message that's going to be sent. Each message has to be handled separately.
int methodStatus = methodName();
if (darwinStarted != -1) {
result.success(methodStatus);
} else {
result.error("FAILED", "Failed to execute methodName.", null);
}
} else {
result.notImplemented(); // Or a fallback can be implemented.
}
}
}
);
}
And in Flutter in order to send a message:
// Connecting to the same channel
static const platform = const MethodChannel("com.example.app/channel");
// Call a method
platform.invokeMethod('methodName');
Native to Flutter
In Flutter, to receive:
// Again connecting to the same channel
static const platform = const MethodChannel("com.example.app/channel");
// In build adding a handler:
@override
Widget build(BuildContext context) {
platform.setMethodCallHandler((MethodCall call) async {
switch (call.method) {
case 'methodName':
return methodName();
default:
return false
}
});
}
And in Java to send:
FlutterNativeView sBackgroundFlutterView = new FlutterNativeView(context, true);
MethodChannel mBackgroundChannel = new MethodChannel(sBackgroundFlutterView, "com.example.app/channel");
mBackgroundChannel.invokeMethod("methodName", null, new Result() {
@Override
public void success(Object o) {
}
@Override
public void error(String s, String s1, Object o) {}
@Override
public void notImplemented() {}
});