Flutter中的同步平台代码执行



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

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

我运行了一些测试,因为我本来打算推迟发送回FlutterResult,直到Swift回调被击中,但这严重地减慢了UI的速度,因为我相信所有平台调用都是在UI线程上进行的。我模拟了10秒的响应时间,应用程序在再次响应之前会完全挂起好几秒钟,如果我发送了一些这样的请求,应用程序会挂起10秒以上。

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

我想

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

等待时表演动画当然是让人头疼的部分。我也不完全确定为什么,因为运行普通CPU工作——无论是原生CPU还是飞镖CPU——都不应该冻结渲染引擎?

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

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

^,如果需要,我可以为上面的设置一个超时计时器来打破循环。

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

不要在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

}

}

最新更新