Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good or Bad: Declaring main method async in Dart / Flutter

Tags:

flutter

dart

I declare one global variable in the entire app - SharedPreferences prefs, and initialize it in main method.

However, SharedPreferences initialization returns a Future - hence I tried awaiting for it to be resolved in main closure of the app:

SharedPreferences prefs;  void main() async {   prefs = await SharedPreferences.getInstance();    runApp(MyApp()); } 

And it worked well. I currently use this method in my 2 apps in production, and it just occurred to me that making main method asynchronous might not be right.

In the end I have 2 questions:

  • How does main method gets invoked and how it works in general in Dart / Flutter?
  • Will making main method of the app asynchronous bring unexpected behaviour? (it hasn't so far)
like image 877
George Avatar asked May 14 '19 11:05

George


People also ask

Can main be async Flutter?

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 .

Is Dart synchronous or asynchronous?

Dart uses Future objects to represent asynchronous operations.

What's the difference between async and async * in Dart?

What is the difference between async and async* in Dart? The difference between both is that async* will always return a Stream and offer some syntax sugar to emit a value through the yield keyword. async gives you a Future and async* gives you a Stream.

Why we use async and await in Dart?

Summary of asynchronous programming in Dart Asynchronous function is a function that returns the type of Future. We put await in front of an asynchronous function to make the subsequence lines waiting for that future's result. We put async before the function body to mark that the function support await .


Video Answer


2 Answers

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.

like image 81
jamesdlin Avatar answered Sep 29 '22 01:09

jamesdlin


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 .

like image 44
Daniel V. Avatar answered Sep 29 '22 01:09

Daniel V.