diff --git a/packages/flutter/lib/src/foundation/synchronous_future.dart b/packages/flutter/lib/src/foundation/synchronous_future.dart index d214697ad98c..ccdd1073dbde 100644 --- a/packages/flutter/lib/src/foundation/synchronous_future.dart +++ b/packages/flutter/lib/src/foundation/synchronous_future.dart @@ -38,11 +38,11 @@ class SynchronousFuture implements Future { @override Future then(FutureOr Function(T value) onValue, { Function? onError }) { - final dynamic result = onValue(_value); + final FutureOr result = onValue(_value); if (result is Future) { return result; } - return SynchronousFuture(result as R); + return SynchronousFuture(result); } @override diff --git a/packages/flutter/lib/src/services/asset_bundle.dart b/packages/flutter/lib/src/services/asset_bundle.dart index 5b9fadd9e6f2..776035aa6871 100644 --- a/packages/flutter/lib/src/services/asset_bundle.dart +++ b/packages/flutter/lib/src/services/asset_bundle.dart @@ -247,17 +247,24 @@ abstract class CachingAssetBundle extends AssetBundle { /// An [AssetBundle] that loads resources using platform messages. class PlatformAssetBundle extends CachingAssetBundle { @override - Future load(String key) async { + Future load(String key) { final Uint8List encoded = utf8.encoder.convert(Uri(path: Uri.encodeFull(key)).path); - final ByteData? asset = - await ServicesBinding.instance.defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData()); - if (asset == null) { + final Future? future = ServicesBinding.instance.defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData())?.then((ByteData? asset) { + if (asset == null) { + throw FlutterError.fromParts([ + _errorSummaryWithKey(key), + ErrorDescription('The asset does not exist or has empty data.'), + ]); + } + return asset; + }); + if (future == null) { throw FlutterError.fromParts([ - _errorSummaryWithKey(key), - ErrorDescription('The asset does not exist or has empty data.'), - ]); + _errorSummaryWithKey(key), + ErrorDescription('The asset does not exist or has empty data.'), + ]); } - return asset; + return future; } @override diff --git a/packages/flutter_test/lib/src/_binding_io.dart b/packages/flutter_test/lib/src/_binding_io.dart index 0dc72180fde8..468dd9b5d548 100644 --- a/packages/flutter_test/lib/src/_binding_io.dart +++ b/packages/flutter_test/lib/src/_binding_io.dart @@ -6,8 +6,8 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; import 'package:path/path.dart' as path; // ignore: deprecated_member_use import 'package:test_api/test_api.dart' as test_package; @@ -42,7 +42,7 @@ void mockFlutterAssets() { /// platform messages. SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {}); - ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) async { + ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) { assert(message != null); String key = utf8.decode(message!.buffer.asUint8List()); File asset = File(path.join(assetFolderPath, key)); @@ -62,7 +62,7 @@ void mockFlutterAssets() { } final Uint8List encoded = Uint8List.fromList(asset.readAsBytesSync()); - return Future.value(encoded.buffer.asByteData()); + return SynchronousFuture(encoded.buffer.asByteData()); }); } diff --git a/packages/flutter_test/test/bindings_test.dart b/packages/flutter_test/test/bindings_test.dart index 8773abfc278d..8e5a31690a70 100644 --- a/packages/flutter_test/test/bindings_test.dart +++ b/packages/flutter_test/test/bindings_test.dart @@ -10,6 +10,7 @@ import 'dart:async'; import 'dart:io'; +import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -90,4 +91,13 @@ void main() { binding.idle(); }); }); + + testWidgets('Assets in the tester can be loaded without turning event loop', (WidgetTester tester) async { + bool responded = false; + // The particular asset does not matter, as long as it exists. + rootBundle.load('AssetManifest.json').then((ByteData data) { + responded = true; + }); + expect(responded, true); + }); }