Method Channel је механизам двосмерне комуникације између Dart кода и изворне стране iOS и Android у Flutter-у. Према Flutter Documentation, 2026, Method Channel обезбеђује пренос типизованих порука између Dart-а и платформе домаћина. Без овог механизма немогуће је приступити хардверским могућностима уређаја, изворним SDK-овима и системским позивима из кода апликације.
Главно
Method Channel је централна компонента платформског слоја Flutter-а кроз коју Dart изолати размењују поруке са апликацијом домаћином на iOS или Android-у. Основни задатак канала је да сакрије разлике у протоколима преноса података између две платформе и пружи јединствени API за програмера.
Када Flutter апликација захтева приступ камери, Bluetooth-у, сензорима или било ком другом изворном API-ју, директни позив из Dart-а није могућ. Flutter ради у мотору на C++-у и нема приступ UIKit или Android SDK оквирима. Method Channel решава овај проблем стварајући мост између света Dart-а и света изворног кода.
Према Google I/O 2024, више од 80% Flutter апликација у продукцији користи најмање један Method Channel за интеграцију са платформским услугама. Ово потврђује критичну улогу канала у архитектури савремених пројеката.
За програмера, Method Channel изгледа као позив обичне асинхроне функције. Испод хаубе се дешава серијализација поруке, пренос кроз бафер мотора и извршавање изворног кода на главној нити платформе.
Интеракција кроз Method Channel почиње тако што Dart страна шаље поруку која садржи име методе и аргументе. Flutter Engine прима ову поруку, претвара је у стандардни формат StandardMethodCodec и прослеђује изворној страни преко BinaryMessenger-а.
Изворна страна садржи руковаоца — MethodCallHandler, који прима десеријализовани позив и извршава одговарајућу логику. Резултат се враћа назад у Dart у облику Response-а који садржи или успешан резултат или грешку са кодом и поруком.
Цео циклус позива кроз Method Channel може се поделити на шест фаза. Dart изолат креира инстанцу канала са јединственим именом за идентификацију везе. При позиву invokeMethod, платформски Dart код серијализује име методе и аргументе помоћу MethodCodec-а, који их претвара у бинарни бафер кроз StandardMessageCodec.
Flutter Engine преноси овај бафер преко сокета на изворну страну. Изворни BinaryMessenger чита поруку, идентификује канал по имену и позива регистрованог руковаоца, прослеђујући му објекат FlutterMethodCall са обрађеним подацима. Руковалац извршава потребан код и враћа резултат, који пролази обрнути пут серијализације и стиже у Dart као Future.
Архитектура Method Channel-а састоји се од неколико међусобно повезаних ентитета, од којих је сваки одговоран за своју фазу преноса података. Dart API пружа класу MethodChannel, која од програмера скрива нискоризиони детаљи серијализације и рутирања.
BinaryMessenger је нискоризиони интерфејс Flutter Engine-а за слање и примање бинарних порука између Dart-а и платформе домаћина. Сваки MethodChannel се везује за одређени BinaryMessenger, који обезбеђује рутирање по имену канала. На Dart страни користи се класа BinaryMessenger, на Android-у — BinaryMessenger из пакета io.flutter.embedding.engine, на iOS-у — протокол FlutterBinaryMessenger.
MethodCodec је кодер који претвара позиве метода и повратне вредности у бинарни формат. Flutter се испоручује са две уграђене имплементације: StandardMethodCodec (подразумевано) и JSONMethodCodec (за JSON стрингове). StandardMethodCodec испод хаубе користи StandardMessageCodec, који серијализује податке са подршком за све основне типове Dart-а.
StandardMessageCodec подржава ограничени скуп типова података за обезбеђивање компатибилности између Dart-а, Kotlin-а и Swift-а. У скуп спадају: null, bool, int, double, String, Uint8List, Int32List, Int64List, Float64List, List и Map са кључевима-стринговима.
Сви остали типови — DateTime, DTO објекти или прилагођене класе — морају бити претворени у један од наведених формата. Најчешћи приступ је серијализација сложених објеката у Map са пољима и обнављање структуре на примајућој страни из речника поља.
За пренос великих бинарних података, попут слика са камере, Flutter препоручује коришћење BasicMessageChannel-а са Uint8List како би се избегло потпуно копирање бафера при сваком позиву кроз MethodChannel.
| Dart тип | Kotlin тип | Swift тип |
|---|---|---|
| null | null | nil |
| bool | Boolean | NSNumber |
| int | Int | NSNumber |
| double | Double | NSNumber |
| String | String | NSString |
| Uint8List | ByteArray | FlutterStandardTypedData |
| List | List | Array |
| Map | HashMap | Dictionary |
Подешавање Method Channel-а на Android страни врши се у класи која имплементира FlutterPlugin или директно у MainActivity-ју. Први приступ је препоручен јер обезбеђује правилно управљање животним циклусом додатка и компатибилност са add-to-app сценаријима.
Након креирања инстанце канала са истим именом као на Dart страни, потребно је регистровати MethodCallHandler преко setMethodCallHandler-а. Унутар руковаоца програмер проверава име долазне методе кроз when и враћа резултат преко result.success или грешку преко result.error са кодом и поруком.
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()
}
}
}
}
У овом примеру, канал под именом samples.flutter.dev/battery обрађује позив getBatteryLevel, добија ниво батерије преко Android BatteryManager-а и враћа га у Dart код. Име канала мора бити исто на обе стране, иначе порука неће стићи до руковаоца.
За продукциони код препоручује се издвајање логике Method Channel-а у посебну класу која имплементира FlutterPlugin. Ово омогућава поновну употребу додатка између пројеката и гарантује правилно чишћење ресурса при позиву onDetachedFromEngine. Додатак се региструје кроз registerWith и може се тестирати изоловано од Activity-ја.
Method Channel на iOS-у се подешава у класи која имплементира протокол FlutterPlugin или у AppDelegate-у. Препоручени начин је креирање посебне класе додатка која се региструје кроз FlutterPluginRegistrar и којом управља Flutter Engine.
Dart страна шаље позив, изворни руковалац прима објекат FlutterMethodCall са именом методе и аргументима. Програмер одређује позвану методу кроз switch по call.method и враћа резултат кроз затварање result. За приступ iOS API-ју користе се UIKit и други системски оквири.
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 приступ гарантује правилну регистрацију и искључивање додатка при уништењу Flutter Engine-а. У Swift руковаоцу користи се switch по call.method, сваки case враћа резултат кроз затварање result. Аргументи су доступни кроз call.arguments са претварањем у одговарајући тип.
При раду са Method Channel-ом важно је поштовати неколико кључних правила за обезбеђивање перформанси и стабилности апликације. Основна препорука је минимизирање броја и обима пренетих података, посебно при позивима у петљама анимације или са високом фреквенцијом.
На изворној страни увек треба обрадити изузетке и вратити грешку кроз result.error са поруком читљивом за човека. На Dart страни сваки позив invokeMethod мора бити умотан у try-catch за хватање PlatformException-а. Игнорисање грешака може довести до неочекиваног пада апликације без разумљивог разлога.
Подразумевано, Method Channel извршава изворни код на главној нити платформе. Ако руковалац извршава тешку операцију, потребно је преместити извршавање у позадинску нит помоћу Kotlin Coroutines на Android-у или Grand Central Dispatch на iOS-у. Враћање резултата кроз result треба да се деси тек након завршетка рада на главној нити.
Бирајте јединствена имена за канале користећи обрнуту доменску нотацију — на пример, com.example.app/feature. Кратка имена могу бити у конфликту са другим додацима. Flutter региструје канале глобално, стога идентична имена у различитим додацима доводе до преписивања руковаоца и нерадних позива.
Често постављана питања
MethodChannel је намењен позивању метода по шеми позив-одговор са кодирањем кроз MethodCodec. BasicMessageChannel преноси произвољне поруке без формата методе и аргумената, што је згодно за стримовне податке и догађаје са платформе.
Директно — не. StandardMessageCodec подржава само основне типове: примитиве, String, Uint8List, List и Map. Прилагођени објекти морају се ручно серијализовати у Map пре слања и обновити на примајућој страни из речника поља.
На изворној страни користите result.error са кодом грешке и поруком. На Dart страни умотајте invokeMethod у try-catch и хватајте PlatformException. Ако метода није имплементирана на платформи, вратите result.notImplemented.
Сваки позив извршава серијализацију и копирање података између изолата и платформи. За ретке позиве додатни трошак је занемарљив. При преносу мегабајта података по кадру могуће су кашњења и пад FPS-а. За стримовне податке користите платформске приказе или текстурне рендер објекте.
Користите EventChannel — он је намењен за стримовање догађаја са изворне стране на Dart. Платформа покреће слање кроз EventSink, а Dart се претплаћује на ток помоћу receiveBroadcastStream. Method Channel није погодан за овај сценарио.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.