有没有办法从setMethodCallHandler获取Future?

时间:2018-04-15 22:45:47

标签: dart flutter

我有一个setMethodCallHandler从我的Java代码运行回调,我希望它设置一个包含结果的Future。像

这样的东西
Future<String> fun() async {

  return setMethodCallHandler((MethodCall call) {
    return () async {return call.arguments["arg"];}();
  });
}

我希望能够做的是call.argument将返回“abc”,

var a = await fun();

a将等于“abc”

我找到的唯一信息是关于setMethodCallHandler的文档:

  

如果处理程序返回的未来完成了结果,则该值将被发送回平台插件调用程序,该调用程序包含在此通道编解码器定义的成功包络中。如果将来使用PlatformException完成,那么该异常的字段将用于填充发送回的错误信封。

但我不明白如何才能将“平台插件调用者包含在此频道编解码器定义的成功信封中”?

2 个答案:

答案 0 :(得分:2)

我猜,但是如果我错了,请纠正我,setMethodCallHandler不返回值,它只设置一个稍后调用的函数。 因此,您无法使用setMethodCallHandler的返回值。

这实际上意味着你有一种“事件”,一种你想要“转换”成未来完成的事件。为此,您可以使用Completer创建并稍后完成Future

Future<String> fun() {
  var completer = new Completer<String>();
  setMethodCallHandler((MethodCall call) {
    completer.complete(call.arguments["arg"]);
  }
  return completer.future;
}

当您的事件全部来自期货或流,但当您获得其他类型的事件(如端口事件,I / O回调或计时器)并且您希望将其映射回未来时,使用async函数会起作用/ stream事件,您可以使用Completer来完成未来,也可以使用StreamController将事件添加到流中。

答案 1 :(得分:0)

我是否理解您正在尝试实现一种从本机Android端调用Flutter Dart代码的方法(这与您在Flutter代码调用本机时执行此操作的更常见方法相反平台特定的事情,如测量电池电量,或访问相机)? (请注意,如果您只想将本地事件发送到Dart,那么可以使用更简单的方法。)

以更常见的方式在Java端注册处理程序:

  public static void registerWith(Registrar registrar) {
    final MethodChannel channel = new MethodChannel(registrar.messenger(), "myutils");
    channel.setMethodCallHandler(new MyUtilsPlugin(registrar));
  }

并实现MethodCallHandler接口的onMethodCall(MethodCall c, Result r)方法

在Dart结束时,您可以使用

调用本机方法
  static Future<String> get platformVersion =>
      _channel.invokeMethod('getPlatformVersion');

StandardMethodCodec以及StandardMessageCodec负责序列化/转换两半之间的数据类型。

剧透:一些猜测如下......如果你想转过来,你需要在Dart端注册你的方法处理程序

_channel.setMethodCallHandler(myUtilsHandler);

然后实现处理程序

  Future<dynamic> myUtilsHandler(MethodCall methodCall) async {
    switch (methodCall.method) {
      case 'foo':
        return 'some string';
      case 'bar':
        return 123.0;
      default:
        // todo - throw not implemented
    }
  }

在Java端,您使用

调用Dart方法
channel.invokeMethod("foo", parameters, new Result() {/*
    todo provide handlers for success, error, notImplemented
*/});

我不清楚何时注册Dart结束处理程序(来自main()??),以及如何从Dart处理程序中抛出notImplemented或错误 - 我的例子只是处理成功的方法调用