Avoid exceptions for control flow (#46897)
This commit is contained in:
parent
a467932d5b
commit
948e2b0101
@ -140,6 +140,22 @@ class MethodChannel {
|
||||
BinaryMessenger get binaryMessenger => _binaryMessenger ?? defaultBinaryMessenger; // ignore: deprecated_member_use_from_same_package
|
||||
final BinaryMessenger _binaryMessenger;
|
||||
|
||||
@optionalTypeArgs
|
||||
Future<T> _invokeMethod<T>(String method, { bool missingOk, dynamic arguments }) async {
|
||||
assert(method != null);
|
||||
final ByteData result = await binaryMessenger.send(
|
||||
name,
|
||||
codec.encodeMethodCall(MethodCall(method, arguments)),
|
||||
);
|
||||
if (result == null) {
|
||||
if (missingOk) {
|
||||
return null;
|
||||
}
|
||||
throw MissingPluginException('No implementation found for method $method on channel $name');
|
||||
}
|
||||
return codec.decodeEnvelope(result) as T;
|
||||
}
|
||||
|
||||
/// Invokes a [method] on this channel with the specified [arguments].
|
||||
///
|
||||
/// The static type of [arguments] is `dynamic`, but only values supported by
|
||||
@ -309,17 +325,8 @@ class MethodChannel {
|
||||
/// * <https://api.flutter.dev/javadoc/io/flutter/plugin/common/MethodCall.html>
|
||||
/// for how to access method call arguments on Android.
|
||||
@optionalTypeArgs
|
||||
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async {
|
||||
assert(method != null);
|
||||
final ByteData result = await binaryMessenger.send(
|
||||
name,
|
||||
codec.encodeMethodCall(MethodCall(method, arguments)),
|
||||
);
|
||||
if (result == null) {
|
||||
throw MissingPluginException('No implementation found for method $method on channel $name');
|
||||
}
|
||||
final T typedResult = codec.decodeEnvelope(result) as T;
|
||||
return typedResult;
|
||||
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) {
|
||||
return _invokeMethod<T>(method, missingOk: false, arguments: arguments);
|
||||
}
|
||||
|
||||
/// An implementation of [invokeMethod] that can return typed lists.
|
||||
@ -425,12 +432,7 @@ class OptionalMethodChannel extends MethodChannel {
|
||||
|
||||
@override
|
||||
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async {
|
||||
try {
|
||||
final T result = await super.invokeMethod<T>(method, arguments);
|
||||
return result;
|
||||
} on MissingPluginException {
|
||||
return null;
|
||||
}
|
||||
return super._invokeMethod<T>(method, missingOk: true, arguments: arguments);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -42,6 +42,7 @@ void main() {
|
||||
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
|
||||
const MethodCodec jsonMethod = JSONMethodCodec();
|
||||
const MethodChannel channel = MethodChannel('ch7', jsonMethod);
|
||||
const OptionalMethodChannel optionalMethodChannel = OptionalMethodChannel('ch8', jsonMethod);
|
||||
test('can invoke method and get result', () async {
|
||||
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
|
||||
'ch7',
|
||||
@ -157,6 +158,14 @@ void main() {
|
||||
fail('MissingPluginException expected');
|
||||
}
|
||||
});
|
||||
test('can invoke unimplemented method (optional)', () async {
|
||||
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
|
||||
'ch8',
|
||||
(ByteData message) async => null,
|
||||
);
|
||||
final String result = await optionalMethodChannel.invokeMethod<String>('sayHello', 'hello');
|
||||
expect(result, isNull);
|
||||
});
|
||||
test('can handle method call with no registered plugin', () async {
|
||||
channel.setMethodCallHandler(null);
|
||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||
|
Loading…
x
Reference in New Issue
Block a user