skip to Main Content

Consider this first example:

Future<void> initializeServices() async {
  await notificationService.begin();
  await geotrackingService.begin();
  Navigator.of(context).pop(); // Don't use 'BuildContext's across async gaps.
}

Now, consider this second example:

Future<void> initializeServices() async {
  await notificationService.begin();
  await geotrackingService.begin();
  exitScreen();
  // exitScreenAsync();
}

void exitScreen() {
  Navigator.of(context).pop(); // The compiler is satisfied now.
}

Future<void> exitScreenAsync() async {
  Navigator.of(context).pop(); // The compiler remains satisfied?
}

As you can see, the only difference between these two examples is that the the second example is popping the navigator by calling a function while the first one is not. However, with the second exmaple the compiler is perfectly fine and no warning is displayed.

I find this warning a bit stupid and meaningless. Why do I have to move the code section that makes use of the BuildContext across async gaps to a proxy function just to get rid of this warning?

3

Answers


  1. You should not ignore this warning because it can lead to a runtime error. During the async function the widget can be dismounted or destroyed, resulting in an invalid build context.

    Check if the widget is mounted after the async calls and before using the context every time, like this:

    Future<void> initializeServices() async {
      await notificationService.begin();
      await geotrackingService.begin();
      if (mounted) {
        Navigator.of(context).pop(); 
      }
    }
    

    The warning will disappear but this time you are protected against using an invalid context. In order to use mounted you must be inside a widget class which has this property.

    Login or Signup to reply.
  2. No it’s not useless warning.
    The problem is that after an await, every use of the BuildContext will show this warning. This warning happens because using a BuildContext after an await could happen after the widget is disposed of. This way, the context wouldn’t exist anymore and the app could even crash because of this. Check out the official lint documentation:

    if (context.mounted) Navigator.of(context).pop();
    
    Login or Signup to reply.
  3. Your exitScreen is not an async method, that’s why compiler is satisfied. The initializeServices() is an async method, it contains some future to be awaited before it can use context to pop, that’s why it was complaining.

    If you still wish to use exitScreen it would be proper to check mounted like

    if(mounted) exitScreen();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search