Ognjen Regoje bio photo

MY NAME IS
Ognjen Regoje
BUT YOU CAN CALL ME OGGY


I make things that run on the web (mostly).

More /ABOUT me.

And about /PROJECTS I've been involved in.

Email me at me@ognjen.io

me@ognjen.io Twitter LinkedIn Instagram Github

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() {}
});