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:

  1. When main() has finished executing, the asynchronous functions can resume execution. First, the future returned by gatherNewsReports() completes. Then printDailyNewsDigest() continues executing, printing the news.
  2. 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 or Future.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.

Tags:

Dart

Flutter