diff --git a/packages/flutter/lib/src/foundation/binding.dart b/packages/flutter/lib/src/foundation/binding.dart index 5b7efffaf1..f5c3345977 100644 --- a/packages/flutter/lib/src/foundation/binding.dart +++ b/packages/flutter/lib/src/foundation/binding.dart @@ -363,6 +363,19 @@ abstract class BindingBase { final String methodName = 'ext.flutter.$name'; developer.registerExtension(methodName, (String method, Map parameters) async { assert(method == methodName); + + // VM service extensions are handled as "out of band" messages by the VM, + // which means they are handled at various times, generally ASAP. + // Notably, this includes being handled in the middle of microtask loops. + // While this makes sense for some service extensions (e.g. "dump current + // stack trace", which explicitly doesn't want to wait for a loop to + // complete), Flutter extensions need not be handled with such high + // priority. Further, handling them with such high priority exposes us to + // the possibility that they're handled in the middle of a frame, which + // breaks many assertions. As such, we ensure they we run the callbacks + // on the outer event loop here. + await new Future.delayed(Duration.zero); + dynamic caughtException; StackTrace caughtStack; Map result;