0

我正在调用一个本地 SDK,它会关闭并执行一些 API 调用,这显然是有时间限制的工作。对于这项工作的 90%,我使用双向回调和方法通道调用,以便 Dart 可以调用 Swift,然后 Swift 可以在完成后调用 Dart。

我遇到的问题是当我同步等待 API 响应(或超时)时。

我进行了一些测试,因为我原本打算推迟发送回FlutterResultSwift 回调,但这严重减慢了 UI,因为我相信所有平台调用都是在 UI 线程上进行的。我模拟了 10 秒的响应时间,应用程序将完全挂起几秒钟,然后再次响应,如果我向其中一些请求发送垃圾邮件,应用程序将挂起 10 秒以上。

我对运行同步平台代码的最佳方式有点困惑,因为我认为不能从隔离中调用平台代码。

我想要

  • 获取用户详细信息
  • 用户按下按钮
  • 等待时显示动画
  • 得到回应并继续前进。

等待时的显示动画当然是卡顿的部分。我不完全确定为什么要么因为运行通用 CPU 工作,无论其本机或飞镖肯定不应该冻结渲染引擎?

无论如何,我唯一能想到的是:

  • Dart 调用平台方法 A
  • 将标志设置AwaitingMethodA为真
  • 立即返回 FlutterResult 但在 Swift 中设置回调
  • while (AwaitingMethodA)....
  • 当 Swift 中的回调命中时,跳转到 UI 线程并将消息发送回 Dart 说完成,这会将 AwaitingMethodA 设置为 false
  • Dart 代码继续....

^ 如果需要,我可以为上述设置超时计时器以中断循环。

这种方法有什么问题吗,或者对于同步的、有时限的平台工作是否有更好的约定?

4

1 回答 1

0

不要在 while 循环中等待——这就是问题所在。

您应该使用 Completer 类(https://api.flutter.dev/flutter/dart-async/Completer-class.html)。正如文档所说 - 使用 Completer,您可以轻松地将基于回调的 API 转换为基于未来的 API。

您的代码可能如下所示:


class SdkResultType {
//let's assume this is the type that Sdk will return
}

class MyClass {
   Completer _completer;

   Future<SdkResultType> callSdk() {
      _completer=Completer();
      ///this is where you would call the SDK
      somehowCallTheSDK();
      
      // this is where your code will wait
      return _completer.future;
   }

   // your SDK callback - SDK should call this when completed
   void sdkCallback(SdkResultType  sdkResult) {
      if (!_completer.isCompleted) {
         //this is where you complete the _completer.future, unblocking your mainSdkCall function.
         _completer.complete(sdkResult);
      }
   }

   void mainSdkCall() async {
     //this is whare you wait
     var sdkResult=await callSdk();
     
     // do the rest here
     

   }



}
于 2021-03-30T10:27:18.453 回答