1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'package:flutter/foundation.dart';
6
7import 'platform_channel.dart';
8
9export 'dart:typed_data' show ByteData;
10
11/// A message encoding/decoding mechanism.
12///
13/// Both operations throw an exception, if conversion fails. Such situations
14/// should be treated as programming errors.
15///
16/// See also:
17///
18/// * [BasicMessageChannel], which use [MessageCodec]s for communication
19/// between Flutter and platform plugins.
20abstract class MessageCodec<T> {
21 /// Encodes the specified [message] in binary.
22 ///
23 /// Returns null if the message is null.
24 ByteData? encodeMessage(T message);
25
26 /// Decodes the specified [message] from binary.
27 ///
28 /// Returns null if the message is null.
29 T? decodeMessage(ByteData? message);
30}
31
32/// A command object representing the invocation of a named method.
33@pragma('vm:keep-name')
34@immutable
35class MethodCall {
36 /// Creates a [MethodCall] representing the invocation of [method] with the
37 /// specified [arguments].
38 const MethodCall(this.method, [this.arguments]);
39
40 /// The name of the method to be called.
41 final String method;
42
43 /// The arguments for the method.
44 ///
45 /// Must be a valid value for the [MethodCodec] used.
46 ///
47 /// This property is `dynamic`, which means type-checking is skipped when accessing
48 /// this property. To minimize the risk of type errors at runtime, the value should
49 /// be cast to `Object?` when accessed.
50 final dynamic arguments;
51
52 @override
53 String toString() => '${objectRuntimeType(this, 'MethodCall')}($method, $arguments)';
54}
55
56/// A codec for method calls and enveloped results.
57///
58/// All operations throw an exception, if conversion fails.
59///
60/// See also:
61///
62/// * [MethodChannel], which use [MethodCodec]s for communication
63/// between Flutter and platform plugins.
64/// * [EventChannel], which use [MethodCodec]s for communication
65/// between Flutter and platform plugins.
66abstract class MethodCodec {
67 /// Encodes the specified [methodCall] into binary.
68 ByteData encodeMethodCall(MethodCall methodCall);
69
70 /// Decodes the specified [methodCall] from binary.
71 MethodCall decodeMethodCall(ByteData? methodCall);
72
73 /// Decodes the specified result [envelope] from binary.
74 ///
75 /// Throws [PlatformException], if [envelope] represents an error, otherwise
76 /// returns the enveloped result.
77 ///
78 /// The type returned from [decodeEnvelope] is `dynamic` (not `Object?`),
79 /// which means *no type checking is performed on its return value*. It is
80 /// strongly recommended that the return value be immediately cast to a known
81 /// type to prevent runtime errors due to typos that the type checker could
82 /// otherwise catch.
83 dynamic decodeEnvelope(ByteData envelope);
84
85 /// Encodes a successful [result] into a binary envelope.
86 ByteData encodeSuccessEnvelope(Object? result);
87
88 /// Encodes an error result into a binary envelope.
89 ///
90 /// The specified error [code], human-readable error [message] and error
91 /// [details] correspond to the fields of [PlatformException].
92 ByteData encodeErrorEnvelope({required String code, String? message, Object? details});
93}
94
95/// Thrown to indicate that a platform interaction failed in the platform
96/// plugin.
97///
98/// See also:
99///
100/// * [MethodCodec], which throws a [PlatformException], if a received result
101/// envelope represents an error.
102/// * [MethodChannel.invokeMethod], which completes the returned future
103/// with a [PlatformException], if invoking the platform plugin method
104/// results in an error envelope.
105/// * [EventChannel.receiveBroadcastStream], which emits
106/// [PlatformException]s as error events, whenever an event received from the
107/// platform plugin is wrapped in an error envelope.
108class PlatformException implements Exception {
109 /// Creates a [PlatformException] with the specified error [code] and optional
110 /// [message], and with the optional error [details] which must be a valid
111 /// value for the [MethodCodec] involved in the interaction.
112 PlatformException({required this.code, this.message, this.details, this.stacktrace});
113
114 /// An error code.
115 final String code;
116
117 /// A human-readable error message, possibly null.
118 final String? message;
119
120 /// Error details, possibly null.
121 ///
122 /// This property is `dynamic`, which means type-checking is skipped when accessing
123 /// this property. To minimize the risk of type errors at runtime, the value should
124 /// be cast to `Object?` when accessed.
125 final dynamic details;
126
127 /// Native stacktrace for the error, possibly null.
128 ///
129 /// This contains the native platform stack trace, not the Dart stack trace.
130 ///
131 /// The stack trace for Dart exceptions can be obtained using try-catch blocks, for example:
132 ///
133 /// ```dart
134 /// try {
135 /// // ...
136 /// } catch (e, stacktrace) {
137 /// print(stacktrace);
138 /// }
139 /// ```
140 ///
141 /// On Android this field is populated when a `RuntimeException` or a subclass of it is thrown in the method call handler,
142 /// as shown in the following example:
143 ///
144 /// ```kotlin
145 /// import androidx.annotation.NonNull
146 /// import io.flutter.embedding.android.FlutterActivity
147 /// import io.flutter.embedding.engine.FlutterEngine
148 /// import io.flutter.plugin.common.MethodChannel
149 ///
150 /// class MainActivity: FlutterActivity() {
151 /// private val CHANNEL = "channel_name"
152 ///
153 /// override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
154 /// super.configureFlutterEngine(flutterEngine)
155 /// MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
156 /// call, result -> throw RuntimeException("Oh no")
157 /// }
158 /// }
159 /// }
160 /// ```
161 ///
162 /// It is also populated on Android if the method channel result is not serializable.
163 /// If the result is not serializable, an exception gets thrown during the serialization process.
164 /// This can be seen in the following example:
165 ///
166 /// ```kotlin
167 /// import androidx.annotation.NonNull
168 /// import io.flutter.embedding.android.FlutterActivity
169 /// import io.flutter.embedding.engine.FlutterEngine
170 /// import io.flutter.plugin.common.MethodChannel
171 ///
172 /// class MainActivity: FlutterActivity() {
173 /// private val CHANNEL = "channel_name"
174 ///
175 /// override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
176 /// super.configureFlutterEngine(flutterEngine)
177 /// MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
178 /// call, result -> result.success(Object())
179 /// }
180 /// }
181 /// }
182 /// ```
183 ///
184 /// In the cases described above, the content of [stacktrace] will be the unprocessed output of calling `toString()` on the exception.
185 ///
186 /// MacOS, iOS, Linux and Windows don't support querying the native stacktrace.
187 ///
188 /// On custom Flutter embedders this value will be null on platforms that don't support querying the call stack.
189 final String? stacktrace;
190
191 @override
192 String toString() => 'PlatformException($code, $message, $details, $stacktrace)';
193}
194
195/// Thrown to indicate that a platform interaction failed to find a handling
196/// plugin.
197///
198/// See also:
199///
200/// * [MethodChannel.invokeMethod], which completes the returned future
201/// with a [MissingPluginException], if no plugin handler for the method call
202/// was found.
203/// * [OptionalMethodChannel.invokeMethod], which completes the returned future
204/// with null, if no plugin handler for the method call was found.
205class MissingPluginException implements Exception {
206 /// Creates a [MissingPluginException] with an optional human-readable
207 /// error message.
208 MissingPluginException([this.message]);
209
210 /// A human-readable error message, possibly null.
211 final String? message;
212
213 @override
214 String toString() => 'MissingPluginException($message)';
215}
216

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com