You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/ff-concepts/existing-flutter/method-channels.md
+22-34Lines changed: 22 additions & 34 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -80,28 +80,14 @@ This message flow is asynchronous and decoupled:
80
80
* **Method Handler**: Native code uses a handler (e.g., `setMethodCallHandler` on Android) to listen for calls and run logic when the specified method name is matched.
81
81
* **Result Callback**: The native handler must return a result via `result.success(...)`, `result.error(...)`, or `result.notImplemented()`. These responses are passed back to Dart, completing the `Future`.
82
82
83
-
### Example Message Flow {#example-message-flow}
83
+
### Example Message Flow
84
84
85
-
```
86
-
Flutter (Dart)
87
-
|
88
-
|invokeMethod('getBatteryLevel')
89
-
v
90
-
Native (Kotlin/Swift)
91
-
- Listens on 'com.example/battery'
92
-
- Matches method name 'getBatteryLevel'
93
-
- Executes logic to read battery level
94
-
- Sends result back:success(85) or error(...)
95
-
^
96
-
| Future in Dart completes with85 or throws PlatformException
97
-
|
98
-
Flutter (Dart)
99
-
```
85
+

100
86
101
87
This design ensures clear separation between platform and UI logic, and it keeps the UI thread non-blocking for both Dart and native sides. It also makes the communication extensible—you can define as many methods as you need over a single channel or use multiple channels for modular organization.
102
88
103
89
104
-
### When to Use a MethodChannel {#when-to-use-a-methodchannel}
90
+
### When to Use a MethodChannel
105
91
106
92
MethodChannel is most appropriate when:
107
93
@@ -110,21 +96,21 @@ MethodChannel is most appropriate when:
110
96
* You need to launch a platform-native UI (e.g., a full-screen scanner or a native file picker).
111
97
* You’re bridging a legacy native feature into a Flutter app or gradually migrating a native app to Flutter.
112
98
113
-
### What MethodChannels Are Not {#what-methodchannels-are-not}
99
+
### What MethodChannels Are Not
114
100
115
101
* They are not **shared memory** \- All data is copied through serialization, not shared by reference. Only standard types are supported (primitives, lists, maps, typed data). Large data transfers require full serialization/deserialization.
116
102
* They are **not synchronous** \- Calls return Futures immediately without blocking. Results arrive asynchronously via the event loop. Platform errors surface as PlatformExceptions when the Future completes.
117
103
* They are **not opinionated** \- You define the API contract (method names, arguments, types) on both sides. There's no compile-time validation across the boundary \- mismatches fail at runtime. Document your contract and validate inputs since type safety isn't enforced.
118
104
119
105
By understanding these characteristics, you can create robust, maintainable bridges between Dart and native code. You can write minimal, purpose-driven native handlers and keep the rest of your app in Flutter, achieving both deep platform access and cross-platform speed.
120
106
121
-
## Real-World Use Cases for MethodChannels {#real-world-use-cases-for-methodchannels}
107
+
## Real-World Use Cases for MethodChannels
122
108
123
109
While Flutter plugins cover many common platform integrations, there are frequent scenarios where you require direct access to native SDKs or platform-specific APIs. MethodChannels offer a direct path for these integrations without waiting for third-party plugin support.
124
110
125
111
Ultimately, method channel integration is essentially plugin development \- you're writing the same native bridge packaged for your app instead of as a public package. Once complete, it can be imported into FlutterFlow. The following examples show when building your own native integration is more practical than waiting for or wrestling with existing plugins. The following examples outline situations where MethodChannels are suitable.
126
112
127
-
1. **Accessing Device Hardware Not Exposed by Plugins**
113
+
### Accessing Device Hardware Not Exposed by Plugins
128
114
129
115
**Example:** Retrieve mobile network signal strength, advanced battery metrics, or thermal status.
130
116
@@ -134,7 +120,7 @@ Ultimately, method channel integration is essentially plugin development \- you'
134
120
135
121
**Benefit:** Access hardware-level telemetry or diagnostics crucial for field-service apps, testing tools, or enterprise reporting.
136
122
137
-
2. **Integrating Proprietary SDKs or Vendor Libraries**
123
+
### Integrating Proprietary SDKs or Vendor Libraries
138
124
139
125
**Example:** Use a third-party identity verification SDK, document scanner, or encrypted storage SDK.
140
126
@@ -144,7 +130,7 @@ Ultimately, method channel integration is essentially plugin development \- you'
144
130
145
131
**Benefit:** Unlocks core business features (KYC, biometrics, payments) without dependency on plugin authors or external wrappers.
146
132
147
-
3. **Embedding Native UI Views Temporarily**
133
+
### Embedding Native UI Views Temporarily
148
134
149
135
**Example:** Show a native PDF viewer, a camera UI from a vendor SDK, or an AR interface.
150
136
@@ -153,7 +139,7 @@ Ultimately, method channel integration is essentially plugin development \- you'
153
139
154
140
**Benefit:** Delivers platform-native experiences where needed while preserving Flutter’s rendering pipeline elsewhere.
155
141
156
-
4. **Background Tasks and Event-Driven Native APIs**
142
+
### Background Tasks and Event-Driven Native APIs
157
143
158
144
**Example:** Respond to geofencing events, push token refresh, or Bluetooth device state changes.
159
145
@@ -163,7 +149,7 @@ Ultimately, method channel integration is essentially plugin development \- you'
163
149
164
150
**Benefit:** Achieves OS-level integration (e.g., location, power, Bluetooth) without polling or Dart-side complexity.
165
151
166
-
5. **Secure Device Data Retrieval**
152
+
### Secure Device Data Retrieval
167
153
168
154
**Example:** Fetch IMEI, MAC address, device fingerprint, or system identifiers.
169
155
@@ -267,22 +253,24 @@ class MainActivity: FlutterActivity() {
267
253
268
254
**Notes:**
269
255
270
-
* Always return a result using one of the following:
256
+
- Always return a result using one of the following:
271
257
* `result.success(data)` — returns data to Dart
272
258
* `result.error(code, message, details)` — throws `PlatformException` in Dart
273
259
* `result.notImplemented()` — throws `MissingPluginException` in Dart
274
-
* Do **not** call `result` multiple times. Flutter expects a one-time, one-result reply per method call.
275
-
* If your native call involves I/O, network, or anything that blocks, use a background thread:
276
-
260
+
- Do **not** call `result` multiple times. Flutter expects a one-time, one-result reply per method call.
261
+
- If your native call involves I/O, network, or anything that blocks, use a background thread:
0 commit comments