Method Channel je mechanismus obousměrné komunikace mezi Dart kódem a nativní stranou iOS a Android v Flutter. Podle Flutter Documentation, 2026, Method Channel zajišťuje přenos typovaných zpráv mezi Dart a hostitelskou platformou. Bez tohoto mechanismu není možné přistupovat k hardwarovým možnostem zařízení, nativním SDK a systémovým voláním z kódu aplikace.
Hlavní body
Method Channel je centrální komponenta platformové vrstvy Flutter, prostřednictvím které si Dart izoláty vyměňují zprávy s hostitelskou aplikací na iOS nebo Android. Hlavním úkolem kanálu je skrýt rozdíly v protokolech přenosu dat mezi dvěma platformami a poskytnout jednotné API pro vývojáře.
Když Flutter aplikace vyžaduje přístup k fotoaparátu, Bluetooth, senzorům nebo jakémukoli jinému nativnímu API, přímé volání z Dart není možné. Flutter běží v enginu na C++ a nemá přístup k frameworkům UIKit nebo Android SDK. Method Channel řeší tento problém vytvořením mostu mezi světem Dart a světem nativního kódu.
Podle Google I/O 2024 používá více než 80% Flutter aplikací v produkci alespoň jeden Method Channel pro integraci s platformovými službami. To potvrzuje kritickou roli kanálu v architektuře moderních projektů.
Pro vývojáře vypadá Method Channel jako volání běžné asynchronní funkce. Pod kapotou probíhá serializace zprávy, přenos přes buffer enginu a provedení nativního kódu na hlavním vlákně platformy.
Interakce prostřednictvím Method Channel začíná tím, že strana Dart odešle zprávu obsahující název metody a argumenty. Flutter Engine tuto zprávu přijme, převede ji do standardního formátu StandardMethodCodec a předá jí nativní straně prostřednictvím BinaryMessenger.
Nativní strana obsahuje handler — MethodCallHandler, který obdrží deserializované volání a provede odpovídající logiku. Výsledek je vrácen zpět do Dart ve formě Response obsahující buď úspěšný výsledek, nebo chybu s kódem a zprávou.
Celý cyklus volání prostřednictvím Method Channel lze rozdělit do šesti fází. Dart izolát vytvoří instanci kanálu s jedinečným názvem pro identifikaci spojení. Při volání invokeMethod Dart platformový kód serializuje název metody a argumenty pomocí MethodCodec, který je převede na binární buffer prostřednictvím StandardMessageCodec.
Flutter Engine předá tento buffer přes socket nativní straně. Nativní BinaryMessenger přečte zprávu, identifikuje kanál podle názvu a zavolá registrovaný handler, kterému předá objekt FlutterMethodCall s parsovanými daty. Handler provede potřebný kód a vrátí výsledek, který projde obrácenou cestou serializace a vstoupí do Dart jako Future.
Architektura Method Channel se skládá z několika vzájemně propojených entit, z nichž každá je zodpovědná za svou fázi přenosu dat. Dart API poskytuje třídu MethodChannel, která před vývojářem skrývá nízkoúrovňové detaily serializace a směrování.
BinaryMessenger je nízkoúrovňové rozhraní Flutter Engine pro odesílání a přijímání binárních zpráv mezi Dart a hostitelskou platformou. Každý MethodChannel je vázán na konkrétní BinaryMessenger, který zajišťuje směrování podle názvu kanálu. Na straně Dart se používá třída BinaryMessenger, na Android — BinaryMessenger z balíčku io.flutter.embedding.engine, na iOS — protokol FlutterBinaryMessenger.
MethodCodec je kodér, který převádí volání metod a vrácené hodnoty do binárního formátu. Flutter je dodáván se dvěma vestavěnými implementacemi: StandardMethodCodec (výchozí) a JSONMethodCodec (pro JSON řetězce). StandardMethodCodec pod kapotou používá StandardMessageCodec, který serializuje data s podporou všech základních typů Dart.
StandardMessageCodec podporuje omezenou sadu typů dat pro zajištění kompatibility mezi Dart, Kotlin a Swift. Sada zahrnuje: null, bool, int, double, String, Uint8List, Int32List, Int64List, Float64List, List a Map s klíči-řetězci.
Všechny ostatní typy — DateTime, DTO objekty nebo vlastní třídy — musí být převedeny do jednoho z uvedených formátů. Nejběžnějším přístupem je serializace složitých objektů do Map s poli a obnovení struktury na přijímající straně ze slovníku polí.
Pro přenos velkých binárních dat, jako jsou obrázky z fotoaparátu, Flutter doporučuje použití BasicMessageChannel s Uint8List, aby se předešlo úplnému kopírování bufferu při každém volání přes MethodChannel.
| Dart typ | Kotlin typ | Swift typ |
|---|---|---|
| null | null | nil |
| bool | Boolean | NSNumber |
| int | Int | NSNumber |
| double | Double | NSNumber |
| String | String | NSString |
| Uint8List | ByteArray | FlutterStandardTypedData |
| List | List | Array |
| Map | HashMap | Dictionary |
Nastavení Method Channel na straně Android se provádí ve třídě implementující FlutterPlugin nebo přímo v MainActivity. První přístup je doporučen, protože zajišťuje správnou správu životního cyklu pluginu a kompatibilitu se scénáři add-to-app.
Po vytvoření instance kanálu se stejným názvem jako na straně Dart je nutné zaregistrovat MethodCallHandler prostřednictvím setMethodCallHandler. Uvnitř handleru vývojář zkontroluje název příchozí metody pomocí when a vrátí výsledek prostřednictvím result.success nebo chybu prostřednictvím result.error s kódem a zprávou.
package com.example.app
import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodChannel
class MainActivity : FlutterActivity() {
private val CHANNEL = "samples.flutter.dev/battery"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
val channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
channel.setMethodCallHandler { call, result ->
when (call.method) {
"getBatteryLevel" -> {
val batteryLevel = getBatteryLevel()
if (batteryLevel != null) {
result.success(batteryLevel)
} else {
result.error("UNAVAILABLE", "Battery not available", null)
}
}
else -> result.notImplemented()
}
}
}
}
V tomto příkladu kanál s názvem samples.flutter.dev/battery zpracovává volání getBatteryLevel, získává úroveň baterie prostřednictvím Android BatteryManager a vrací ji do Dart kódu. Název kanálu musí být stejný na obou stranách, jinak zpráva nedorazí k handleru.
Pro produkční kód se doporučuje vyčlenit logiku Method Channel do samostatné třídy implementující FlutterPlugin. To umožňuje znovupoužití pluginu mezi projekty a zaručuje správné čištění zdrojů při volání onDetachedFromEngine. Plugin se registruje prostřednictvím registerWith a může být testován izolovaně od Activity.
Method Channel na iOS se nastavuje ve třídě implementující protokol FlutterPlugin nebo v AppDelegate. Doporučeným způsobem je vytvoření samostatné třídy pluginu, která se registruje prostřednictvím FlutterPluginRegistrar a je spravována Flutter Engine.
Strana Dart odešle volání, nativní handler obdrží objekt FlutterMethodCall s názvem metody a argumenty. Vývojář určí volanou metodu pomocí switch podle call.method a vrátí výsledek prostřednictvím closure result. Pro přístup k iOS API se používá UIKit a další systémové frameworky.
import Flutter
import UIKit
public class BatteryPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(
name: "samples.flutter.dev/battery",
binaryMessenger: registrar.messenger())
let instance = BatteryPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "getBatteryLevel":
let device = UIDevice.current
device.isBatteryMonitoringEnabled = true
let level = Int(device.batteryLevel * 100)
result(level)
default:
result(FlutterMethodNotImplemented)
}
}
}
Přístup FlutterPlugin zaručuje správnou registraci a deaktivaci pluginu při zničení Flutter Engine. Ve Swift handleru se používá switch podle call.method, každý case vrací výsledek prostřednictvím closure result. Argumenty jsou přístupné prostřednictvím call.arguments s převodem na odpovídající typ.
Při práci s Method Channel je důležité dodržovat několik klíčových pravidel pro zajištění výkonu a stability aplikace. Hlavním doporučením je minimalizace počtu a objemu přenášených dat, zejména při voláních v cyklech animace nebo s vysokou frekvencí.
Na nativní straně je vždy nutné zpracovat výjimky a vrátit chybu prostřednictvím result.error s čitelnou zprávou. Na straně Dart musí být každé volání invokeMethod zabaleno do try-catch pro zachycení PlatformException. Ignorování chyb může vést k neočekávanému pádu aplikace bez srozumitelné příčiny.
Ve výchozím nastavení Method Channel provádí nativní kód na hlavním vlákně platformy. Pokud handler provádí těžkou operaci, je nutné přesunout provedení na vlákno na pozadí pomocí Kotlin Coroutines na Android nebo Grand Central Dispatch na iOS. Vrácení výsledku prostřednictvím result by mělo nastat až po dokončení práce na hlavním vlákně.
Vybírejte jedinečné názvy kanálů pomocí reverzní doménové notace — například com.example.app/feature. Krátké názvy mohou kolidovat s jinými pluginy. Flutter registruje kanály globálně, proto identické názvy v různých pluginech vedou k přepsání handleru a nefunkčním voláním.
Často kladené otázky
MethodChannel je určen pro volání metod ve schématu volání-odpověď s kódováním prostřednictvím MethodCodec. BasicMessageChannel přenáší libovolné zprávy bez formátu metody a argumentů, což je vhodné pro streamovaná data a události z platformy.
Přímo — ne. StandardMessageCodec podporuje pouze základní typy: primitiva, String, Uint8List, List a Map. Vlastní objekty je nutné ručně serializovat do Map před odesláním a obnovit na přijímající straně ze slovníku polí.
Na nativní straně použijte result.error s kódem chyby a zprávou. Na straně Dart zabalte invokeMethod do try-catch a zachyťte PlatformException. Pokud metoda není na platformě implementována, vraťte result.notImplemented.
Každé volání provádí serializaci a kopírování dat mezi izoláty a platformami. Při vzácných voláních je režie zanedbatelná. Při přenosu megabajtů dat na snímek mohou nastat zpoždění a pokles FPS. Pro streamovaná data používejte platformová zobrazení nebo texturové renderovací objekty.
Použijte EventChannel — je určen pro streamování událostí z nativní strany do Dart. Platforma iniciuje odeslání prostřednictvím EventSink a Dart se přihlásí k odběru streamu pomocí receiveBroadcastStream. Method Channel není pro tento scénář vhodný.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.