Good or Bad: Declaring main method async in Dart / Flutter
Good one from @jamesdlin .
A literal answer for your question
How does main method gets invoked and how it works in general in Dart / Flutter?
For Android apps, Dart entry point is invoked via DartExecutor
. You can take a look at here: DartExecutor class
There is a brief document, how you can manually do what FlutterApplication does for you: wiki/Experimental:-Launch-Flutter-with-non-main-entrypoint
Classes you want to look for, if you want to dig deeper: FlutterApplication
, FlutterActivity
, FlutterMain
.
How does main method gets invoked and how it works in general in Dart / Flutter?
The Dart VM (or the runtime in AOT mode) looks for and executes a function named main
. After main
returns, the VM will wait for pending asynchronous operations to complete before exiting. The Asynchronous programming article on the official Dart website has an example that demonstrates this:
- When
main()
has finished executing, the asynchronous functions can resume execution. First, the future returned bygatherNewsReports()
completes. ThenprintDailyNewsDigest()
continues executing, printing the news.- When the
printDailyNewsDigest()
function body finishes executing, the future that it originally returned completes, and the app exits.
(Note that the exit
function will cause immediate termination without any waiting.)
Will making main method of the app asynchronous bring unexpected behaviour? (it hasn't so far)
No. First, you should keep in mind that the async
keyword is not what makes a function asynchronous. The async
keyword simply enables the use of the await
keyword (which itself is syntactic sugar for registering a Future.then
callback) and (mostly) requires that the function be declared to return a Future
. (I say "mostly" because returning void
instead of Future<void>
is allowed, although dartanalyzer
will complain about that too if the avoid_void_async
lint is enabled.)
Your application will inherently be asynchronous once you invoke any asynchronous function. When you invoke an asynchronous function, you either:
- Wait for it to complete (via
await
orFuture.then
). The caller is then asynchronous too. - The asynchronous operation is unawaited ("fire-and-forget"). But this still means that
main
can return with asynchronous operations still pending.
Either way, your application must wait before terminating (assuming that it didn't encounter abnormal termination from an uncaught exception or exit
).
Since your main
function uses await
, you don't even have a choice about marking it async
.