Method Channel — co to je, vlastnosti fungování a použití ve Flutter

Autor: IT Sectr Publikováno: 2026-06-03 Doba čtení: 9 min

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 — hlavní mechanismus integrace Flutter s nativním kódem iOS a Android.
  • Obousměrná komunikace — Dart kód může volat nativní metody a nativní kód může odesílat data zpět do Dart.
  • Asynchronnost — všechna volání se provádějí asynchronně bez blokování hlavního vlákna.
  • Standardní serializace — data jsou přenášena ve formátu kompatibilním s JSON s podporou primitiv, seznamů a slovníků.
  • BasicMessageChannel — alternativní typ kanálu pro streamování textových nebo binárních zpráv.

Co je Method Channel a k čemu slouží

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.

Jak Method Channel funguje

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.

Proces volání krok za krokem

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: klíčové komponenty

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

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 a MessageCodec

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.

Typy dat a serializace v Method Channel

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 typKotlin typSwift typ
nullnullnil
boolBooleanNSNumber
intIntNSNumber
doubleDoubleNSNumber
StringStringNSString
Uint8ListByteArrayFlutterStandardTypedData
ListListArray
MapHashMapDictionary

Method Channel na Android: nastavení v Kotlin

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.

kotlin
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.

Vytvoření pluginu prostřednictvím FlutterPlugin

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: nastavení ve Swift

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.

swift
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.

Nejlepší postupy Method Channel a časté chyby

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í.

Zpracování chyb

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.

Izolace vláken

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ě.

Pojmenování kanálů

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

Jaký je rozdíl mezi MethodChannel a BasicMessageChannel?

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.

Lze přenášet vlastní objekty prostřednictvím Method Channel?

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í.

Jak zpracovat chyby při volání Method Channel?

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.

Ovlivňuje Method Channel výkon?

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.

Jak přenést událost z platformy do Dart bez volání z Dart?

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í

  • Method Channel — hlavní mechanismus platformové integrace Flutter pro obousměrnou asynchronní komunikaci mezi Dart a nativním kódem iOS a Android.
  • Architektura zahrnuje BinaryMessenger, MethodCodec a MethodCallHandler, které společně zajišťují serializaci, směrování a provádění volání.
  • Typy dat jsou omezeny na sadu StandardMessageCodec: primitiva, řetězce, seznamy, slovníky a typované buffery.
  • Nastavení na Android se provádí prostřednictvím FlutterPlugin s MethodChannel v Kotlin, na iOS prostřednictvím FlutterPlugin s FlutterMethodChannel ve Swift.
  • Výkon vyžaduje minimalizaci velikosti přenášených dat a použití EventChannel pro streamované události.
  • Chyby jsou zpracovávány prostřednictvím result.error na platformě a catch PlatformException na straně Dart.
  • Architektura pluginů s FlutterPlugin je preferována před přímým kódem v Activity, protože zajišťuje správnou správu životního cyklu.

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í.

Prodiskutovat projekt