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
|
BinaryMessenger get binaryMessenger => _binaryMessenger ?? defaultBinaryMessenger; // ignore: deprecated_member_use_from_same_package
|
||||||
final BinaryMessenger _binaryMessenger;
|
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].
|
/// Invokes a [method] on this channel with the specified [arguments].
|
||||||
///
|
///
|
||||||
/// The static type of [arguments] is `dynamic`, but only values supported by
|
/// 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>
|
/// * <https://api.flutter.dev/javadoc/io/flutter/plugin/common/MethodCall.html>
|
||||||
/// for how to access method call arguments on Android.
|
/// for how to access method call arguments on Android.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async {
|
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) {
|
||||||
assert(method != null);
|
return _invokeMethod<T>(method, missingOk: false, arguments: arguments);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An implementation of [invokeMethod] that can return typed lists.
|
/// An implementation of [invokeMethod] that can return typed lists.
|
||||||
@ -425,12 +432,7 @@ class OptionalMethodChannel extends MethodChannel {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async {
|
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async {
|
||||||
try {
|
return super._invokeMethod<T>(method, missingOk: true, arguments: arguments);
|
||||||
final T result = await super.invokeMethod<T>(method, arguments);
|
|
||||||
return result;
|
|
||||||
} on MissingPluginException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -42,6 +42,7 @@ void main() {
|
|||||||
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
|
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
|
||||||
const MethodCodec jsonMethod = JSONMethodCodec();
|
const MethodCodec jsonMethod = JSONMethodCodec();
|
||||||
const MethodChannel channel = MethodChannel('ch7', jsonMethod);
|
const MethodChannel channel = MethodChannel('ch7', jsonMethod);
|
||||||
|
const OptionalMethodChannel optionalMethodChannel = OptionalMethodChannel('ch8', jsonMethod);
|
||||||
test('can invoke method and get result', () async {
|
test('can invoke method and get result', () async {
|
||||||
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
@ -157,6 +158,14 @@ void main() {
|
|||||||
fail('MissingPluginException expected');
|
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 {
|
test('can handle method call with no registered plugin', () async {
|
||||||
channel.setMethodCallHandler(null);
|
channel.setMethodCallHandler(null);
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user