Method Channel är en mekanism för tvåvägskommunikation mellan Dart-kod och nativesidan av iOS och Android i Flutter. Enligt Flutter Documentation, 2026 tillhandahåller Method Channel överföring av typade meddelanden mellan Dart och värdplattformen. Utan denna mekanism är det omöjligt att få tillgång till enhetens hårdvarufunktioner, native SDK:er och systemanrop från applikationskoden.
Huvudpunkter
Method Channel är den centrala komponenten i Flutters plattformslager genom vilken Dart-isolat utbyter meddelanden med värdapplikationen på iOS eller Android. Kanalens huvuduppgift är att dölja skillnaderna i dataöverföringsprotokoll mellan de två plattformarna och tillhandahålla ett enhetligt API för utvecklaren.
När en Flutter-applikation behöver åtkomst till kameran, Bluetooth, sensorer eller något annat native API, är ett direktanrop från Dart omöjligt. Flutter körs i en motor baserad på C++ och har inte tillgång till UIKit- eller Android SDK-ramverken. Method Channel löser detta problem genom att skapa en bro mellan Dart-världen och native-kodvärlden.
Enligt Google I/O 2024 använder mer än 80% av Flutter-applikationer i produktion minst en Method Channel för integration med plattformstjänster. Detta bekräftar kanalens kritiska roll i arkitekturen för moderna projekt.
För utvecklaren ser Method Channel ut som ett anrop till en vanlig asynkron funktion. Under huven sker serialisering av meddelandet, överföring via motorns buffert och exekvering av native-kod på plattformens huvudtråd.
Interaktion via Method Channel börjar med att Dart-sidan skickar ett meddelande som innehåller metodnamnet och argument. Flutter Engine tar emot detta meddelande, omvandlar det till standardformatet StandardMethodCodec och överför det till nativesidan via BinaryMessenger.
Nativesidan innehåller en hanterare — MethodCallHandler, som tar emot det avserialiserade anropet och utför motsvarande logik. Resultatet returneras tillbaka till Dart i form av ett Response som antingen innehåller ett framgångsrikt resultat eller ett fel med kod och meddelande.
Hela anropscykeln via Method Channel kan delas in i sex steg. Dart-isolatet skapar en kanalinstans med ett unikt namn för att identifiera anslutningen. Vid anrop av invokeMethod serialiserar Dart-plattformskoden metodnamnet och argumenten med MethodCodec, som omvandlar dem till en binär buffert via StandardMessageCodec.
Flutter Engine överför denna buffert via en socket till nativesidan. Native BinaryMessenger läser meddelandet, identifierar kanalen efter namn och anropar den registrerade hanteraren och skickar objektet FlutterMethodCall med tolkade data. Hanteraren utför den nödvändiga koden och returnerar resultatet, som går den omvända serialiseringsvägen och kommer in i Dart som en Future.
Arkitekturen för Method Channel består av flera sammankopplade entiteter, var och en ansvarig för sin egen fas av dataöverföring. Dart API tillhandahåller klassen MethodChannel, som döljer detaljerna på låg nivå för serialisering och routning från utvecklaren.
BinaryMessenger är Flutter Engines lågnivågränssnitt för att skicka och ta emot binära meddelanden mellan Dart och värdplattformen. Varje MethodChannel är bunden till en specifik BinaryMessenger som tillhandahåller routning efter kanalnamn. På Dart-sidan används klassen BinaryMessenger, på Android — BinaryMessenger från paketet io.flutter.embedding.engine, på iOS — protokollet FlutterBinaryMessenger.
MethodCodec är en kodare som omvandlar metodanrop och returvärden till binärt format. Flutter levereras med två inbyggda implementationer: StandardMethodCodec (standard) och JSONMethodCodec (för JSON-strängar). StandardMethodCodec använder under huven StandardMessageCodec, som serialiserar data med stöd för alla grundläggande Dart-typer.
StandardMessageCodec stöder en begränsad uppsättning datatyper för att säkerställa kompatibilitet mellan Dart, Kotlin och Swift. Uppsättningen inkluderar: null, bool, int, double, String, Uint8List, Int32List, Int64List, Float64List, List och Map med strängnycklar.
Alla andra typer — DateTime, DTO-objekt eller anpassade klasser — måste konverteras till ett av de angivna formaten. Det vanligaste tillvägagångssättet är att serialisera komplexa objekt till Map med fält och återställa strukturen på den mottagande sidan från fältordboken.
För överföring av stora binära data, såsom bilder från kameran, rekommenderar Flutter användning av BasicMessageChannel med Uint8List för att undvika fullständig kopiering av bufferten vid varje anrop via 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 |
Konfiguration av Method Channel på Android-sidan görs i en klass som implementerar FlutterPlugin eller direkt i MainActivity. Det första tillvägagångssättet rekommenderas eftersom det säkerställer korrekt hantering av pluginets livscykel och kompatibilitet med add-to-app-scenarier.
Efter att ha skapat en kanalinstans med samma namn som på Dart-sidan måste MethodCallHandler registreras via setMethodCallHandler. Inuti hanteraren kontrollerar utvecklaren namnet på den inkommande metoden via when och returnerar resultatet via result.success eller ett fel via result.error med kod och meddelande.
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()
}
}
}
}
I detta exempel behandlar kanalen med namnet samples.flutter.dev/battery anropet getBatteryLevel, hämtar batterinivån via Android BatteryManager och returnerar den till Dart-koden. Kanalens namn måste vara samma på båda sidor, annars når meddelandet inte hanteraren.
För produktionskod rekommenderas att separera Method Channel-logiken i en separat klass som implementerar FlutterPlugin. Detta möjliggör återanvändning av plugin mellan projekt och garanterar korrekt rensning av resurser vid anrop av onDetachedFromEngine. Plugin registreras via registerWith och kan testas isolerat från Activity.
Method Channel på iOS konfigureras i en klass som implementerar protokollet FlutterPlugin eller i AppDelegate. Det rekommenderade sättet är att skapa en separat plugin-klass som registreras via FlutterPluginRegistrar och hanteras av Flutter Engine.
Dart-sidan skickar ett anrop, den native hanteraren tar emot objektet FlutterMethodCall med metodnamnet och argument. Utvecklaren bestämmer den anropade metoden via switch baserat på call.method och returnerar resultatet via closure result. För åtkomst till iOS API används UIKit och andra systemramverk.
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)
}
}
}
FlutterPlugin-metoden garanterar korrekt registrering och avaktivering av plugin när Flutter Engine förstörs. I Swift-hanteraren används switch baserat på call.method, varje case returnerar resultatet via closure result. Argument är tillgängliga via call.arguments med konvertering till lämplig typ.
När du arbetar med Method Channel är det viktigt att följa flera viktiga regler för att säkerställa applikationens prestanda och stabilitet. Huvudrekommendationen är att minimera antalet och volymen av överförda data, särskilt vid anrop i animeringsslingor eller med hög frekvens.
På nativesidan måste du alltid hantera undantag och returnera felet via result.error med ett läsbart meddelande. På Dart-sidan måste varje invokeMethod-anrop omges av try-catch för att fånga PlatformException. Att ignorera fel kan leda till en oväntad krasch av applikationen utan förståelig orsak.
Som standard kör Method Channel native-kod på plattformens huvudtråd. Om hanteraren utför en tung operation måste exekveringen flyttas till en bakgrundstråd med hjälp av Kotlin Coroutines på Android eller Grand Central Dispatch på iOS. Returnering av resultatet via result bör endast ske efter att arbetet på huvudtråden har slutförts.
Välj unika namn för kanaler med omvänd domännotation — till exempel com.example.app/feature. Korta namn kan kollidera med andra plugins. Flutter registrerar kanaler globalt, därför leder identiska namn i olika plugins till överskrivning av hanteraren och icke-fungerande anrop.
Vanliga frågor
MethodChannel är avsett för anrop av metoder i anrop-svar-schema med kodning via MethodCodec. BasicMessageChannel överför godtyckliga meddelanden utan metod- och argumentformat, vilket är bekvämt för strömmande data och händelser från plattformen.
Direkt — nej. StandardMessageCodec stöder endast grundläggande typer: primitiver, String, Uint8List, List och Map. Anpassade objekt måste manuellt serialiseras till Map före sändning och återställas på den mottagande sidan från fältordboken.
På nativesidan använd result.error med felkod och meddelande. På Dart-sidan omge invokeMethod med try-catch och fånga PlatformException. Om metoden inte är implementerad på plattformen, returnera result.notImplemented.
Varje anrop utför serialisering och datakopiering mellan isolat och plattformar. För sällsynta anrop är överhead försumbar. Vid överföring av megabyte data per bildruta kan fördröjningar och FPS-minskning uppstå. För strömmande data, använd plattformsvisningar eller texturrenderobjekt.
Använd EventChannel — det är avsett för strömmande händelser från nativesidan till Dart. Plattformen initierar sändning via EventSink och Dart prenumererar på strömmen med receiveBroadcastStream. Method Channel är inte lämplig för detta scenario.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.