好或坏:在 Dart/Flutter 中声明主方法异步
Posted
技术标签:
【中文标题】好或坏:在 Dart/Flutter 中声明主方法异步【英文标题】:Good or Bad: Declaring main method async in Dart / Flutter 【发布时间】:2019-05-14 11:13:30 【问题描述】:我在整个app中声明了一个全局变量——SharedPreferences prefs
,并在main
方法中初始化。
但是,SharedPreferences
初始化返回一个 Future
- 因此我尝试等待它在应用程序关闭的main
中得到解决:
SharedPreferences prefs;
void main() async
prefs = await SharedPreferences.getInstance();
runApp(MyApp());
而且效果很好。我目前在生产中的 2 个应用程序中使用此方法,我突然想到使 main
方法异步可能不正确。
最后我有两个问题:
main
方法是如何被调用的,以及它在 Dart / Flutter 中的一般工作原理是什么?
使应用程序的main
方法异步会带来意外的行为吗? (到目前为止还没有)
【问题讨论】:
【参考方案1】:在 Dart / Flutter 中 main 方法是如何被调用的以及它是如何工作的?
Dart VM(或 AOT 模式下的运行时)查找并执行名为 main
的函数。在main
返回后,VM 将等待挂起的异步操作完成后再退出。 Dart 官方网站上的Asynchronous programming 文章有一个例子说明了这一点:
main()
执行完毕后,异步函数可以恢复执行。首先,gatherNewsReports()
返回的未来完成。然后printDailyNewsDigest()
继续执行,打印新闻。printDailyNewsDigest()
函数体执行完毕后,它最初返回的 future 完成,应用程序退出。
(请注意exit
function 将导致立即终止而无需任何等待。)
使应用程序的main方法异步会带来意想不到的行为吗? (目前还没有)
没有。首先,您应该记住,async
关键字不是使函数异步的原因。 async
关键字只允许使用await
关键字(它本身是注册Future.then
回调的语法糖)并且(大多数情况下)要求函数声明为返回Future
。 (我说“大部分”是因为允许返回 void
而不是 Future<void>
,尽管如果启用了 avoid_void_async
lint,dartanalyzer
也会抱怨这一点。)
一旦您调用 any 异步函数,您的应用程序将本质上是异步的。当您调用异步函数时,您可以:
等待它完成(通过await
或Future.then
)。调用者也是异步的。
异步操作未等待(“即发即弃”)。但这仍然意味着main
可以在异步操作仍处于挂起状态的情况下返回。
无论哪种方式,您的应用程序都必须在终止之前等待(假设它没有遇到未捕获的异常或exit
导致的异常终止)。
由于您的main
函数使用await
,您甚至无法选择将其标记为async
。
【讨论】:
很好的信息。随着我的应用程序的增长,我发现自己需要从 main 方法进行异步调用。没有发生什么不好的事情,但我一直想知道它是否会破坏某些东西。 官方文档提供了将main方法改为async方法的例子Working with futures: async and await @KexiHe 这与我写的任何内容都没有冲突。我从未说过不应将main
标记为async
或不应返回Future
。【参考方案2】:
来自@jamesdlin 的好作品。
你的问题的字面答案
main 方法是如何被调用的以及它在 Dart 中的一般工作方式 / 颤动?
对于 android 应用,Dart 入口点通过DartExecutor
调用。你可以看看这里:DartExecutor class
有一个简短的文档,你可以如何手动完成 FlutterApplication 为你做的事情: wiki/Experimental:-Launch-Flutter-with-non-main-entrypoint
如果您想深入挖掘,您想查找的课程:FlutterApplication
、FlutterActivity
、FlutterMain
。
【讨论】:
以上是关于好或坏:在 Dart/Flutter 中声明主方法异步的主要内容,如果未能解决你的问题,请参考以下文章
如何在 dart/flutter 中声明 64bit unsigned int?
Dart/flutter:如何在模拟器的本地主机上显示来自 API 的图像