Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call methods in Dart portion of the app, from the native platform using MethodChannel?

I am writing a native plugin that, in some cases, has to call functions in the Flutter portion of the app, written in Dart. How it's achieved, is explained here: https://flutter.io/platform-channels/

Furthermore, an example of invoking a method from the native/platform part towards the Dart/non-native is here: https://github.com/flutter/plugins/tree/master/packages/quick_actions

Now, this example is really nice in case the platform only needs to invoke a method, i.e. that call returns nothing/void, but in case it needs to invoke a function, i.e. needs a return value from the non-native/Dart part, I could not have found an example or documentation on the internet. I believe it can be implemented though, because in the native Java part, there is a method:

public void invokeMethod(String method, Object arguments, MethodChannel.Result callback) 

So, there is a callback object that could have a return value from the non-native part - or, I am mistaken here, and there is currently no way of returning a value from the non-native Dart portion of the app?

like image 882
2beens Avatar asked May 05 '18 09:05

2beens


People also ask

What is MethodChannel?

A named channel for communicating with the Flutter application using asynchronous method calls. Incoming method calls are decoded from binary on receipt, and Java results are encoded into binary before being transmitted back to Flutter.


1 Answers

The signature is void setMethodCallHandler(Future<dynamic> handler(MethodCall call)), so we need to provide a function at the Dart end that returns Future<dynamic>, for example _channel.setMethodCallHandler(myUtilsHandler);

Then implement the handler. This one handles two methods foo and bar returning respectively String and double.

  Future<dynamic> myUtilsHandler(MethodCall methodCall) async {     switch (methodCall.method) {       case 'foo':         return 'some string';       case 'bar':         return 123.0;       default:         throw MissingPluginException('notImplemented');     }   } 

At the Java end the return value is passed to the success method of the Result callback.

channel.invokeMethod("foo", arguments, new Result() {   @Override   public void success(Object o) {     // this will be called with o = "some string"   }    @Override   public void error(String s, String s1, Object o) {}    @Override   public void notImplemented() {} }); 

In Swift, the return value is an Any? passed to the result closure. (Not implemented is signaled by the any parameter being the const NSObject value FlutterMethodNotImplemented.)

channel.invokeMethod("foo", arguments: args, result: {(r:Any?) -> () in   // this will be called with r = "some string" (or FlutterMethodNotImplemented) }) 
like image 113
Richard Heap Avatar answered Sep 24 '22 15:09

Richard Heap