Method Channel — bu, Flutter-də Dart kodu ilə iOS və Android-in native tərəfi arasında ikitərəfli əlaqə mexanizmidir. Flutter Documentation, 2026-ya görə, Method Channel Dart ilə host-platforma arasında tipləşdirilmiş mesajların ötürülməsini təmin edir. Bu mexanizm olmadan proqram kodundan cihazın aparat imkanlarına, native SDK-lara və sistem çağırışlarına daxil olmaq mümkün deyil.
Əsas məqamlar
Method Channel — bu, Flutter platformasının mərkəzi komponentidir. Onun vasitəsilə Dart izolyatları iOS və ya Android-dəki host proqramı ilə mesaj mübadiləsi aparır. Kanalın əsas vəzifəsi iki platforma arasında məlumat ötürülməsi protokollarındakı fərqləri gizlətmək və proqramçı üçün vahid API təmin etməkdir.
Flutter proqramı kameraya, Bluetooth-a, sensorlara və ya hər hansı digər native API-yə daxil olmağa ehtiyac duyduqda, Dart-dan birbaşa çağırış mümkün deyil. Flutter C++ mührrikində işləyir və UIKit və ya Android SDK frameworklərinə çıxışı yoxdur. Method Channel Dart dünyası ilə native kod dünyası arasında körpü yaradaraq bu problemi həll edir.
Google I/O 2024 məlumatlarına görə, istehsalatda olan Flutter proqramlarının 80%-dən çoxu platforma xidmətləri ilə inteqrasiya üçün ən azı bir Method Channel istifadə edir. Bu, müasir layihələrin arxitekturasında kanalın kritik rolunu təsdiqləyir.
Proqramçı üçün Method Channel adi asinxron funksiyanın çağırılması kimi görünür. Arxa planda mesajın serializasiyası, onun mührrik buferi vasitəsilə ötürülməsi və platformanın əsas axınında native kodun yerinə yetirilməsi baş verir.
Qarşılıqlı əlaqə Method Channel vasitəsilə Dart tərəfinin metod adı və arqumentləri əhatə edən mesaj göndərməsi ilə başlayır. Flutter Engine bu mesajı qəbul edir, onu standart StandardMethodCodec formatına çevirir və BinaryMessenger vasitəsilə native tərəfə ötürür.
Native tərəfdə deserializasiya olunmuş çağırışı qəbul edən və müvafiq məntiqi yerinə yetirən bir handler — MethodCallHandler mövcuddur. Nəticə uğur nəticə və ya kod və mesajı olan xəta ilə Response şəklində Dart-a qaytarılır.
Method Channel vasitəsilə bütün çağırış dövri altı mərhələyə bölünə bilər. Dart izolyatı əlaqəni müyyənləşdirmək üçün unikal ada malik kanal nörnəsi yaradır. invokeMethod çağırıldıqda, Dart platforma kodu MethodCodec vasitəsilə metod adını və arqumentləri serializasiya edir, bu da onları StandardMessageCodec vasitəsilə ikili buferə çevirir.
Flutter Engine bu buferi socket vasitəsilə native tərəfə ötürür. Native BinaryMessenger mesajı oxuyur, kanalı adına görə müyyənləşdirir və qeydiyyatdan keçmiş handleri çağıraraq ona parse olunmuş məlumatlarla FlutterMethodCall obyektini ötürür. Handler lazımi kodu yerinə yetirir və nəticəni qaytarır, bu da tərs serializasiya yolundan keçərək Dart-a Future kimi daxil olur.
Method Channel arxitekturası bir-biri ilə əlaqəli bir neçə varlıqdan ibarətdir, onların hər biri məlumat ötürülməsinin öz mərhələsinə cavabdehdir. Dart API proqramçıdan aşağı səviyyəli serializasiya və marşrutlaşdırma detallarını gizlədən MethodChannel sinfini təqdim edir.
BinaryMessenger — Dart ilə host-platforma arasında ikili mesajların göndərilməsi və qəbul edilməsi üçün Flutter Engine-in aşağı səviyyəli interfeysidir. Hər bir MethodChannel kanal adı üzrə marşrutlaşdırmanı təmin edən konkret BinaryMessenger-ə bağlanır. Dart tərəfində BinaryMessenger sinfi, Android-də io.flutter.embedding.engine paketindən BinaryMessenger, iOS-də isə FlutterBinaryMessenger protokolu istifadə olunur.
MethodCodec — metod çağırışlarını və qaytarılan dəyərləri ikili formatda kodlaşdıran kodlaşdırıcıdır. Flutter iki quraşdırılmış tətbiqlə təmin edilir: StandardMethodCodec (standart) və JSONMethodCodec (JSON sətrləri üçün). StandardMethodCodec bütün əsas Dart növlərinin dəstəyi ilə məlumatları serializasiya edən StandardMessageCodec-dən istifadə edir.
StandardMessageCodec Dart, Kotlin və Swift arasında uyğunluğu təmin etmək üçün məhdud məlumat növləri dəstəyi təmin edir. Siyahıya daxildir: null, bool, int, double, String, Uint8List, Int32List, Int64List, Float64List, List və sətir açarları ilə Map.
Bütün digər növlər — DateTime, DTO obyektləri və ya fərdi siniflər — sadalanan formatlardan birinə çevrilməlidir. Ən geniş yayılmış yanaşma mürəkkəb obyektləri sahələri olan Map-ə serializasiya etmək və qəbul edən tərəfdə strukturu sahə lüğətindən bərpa etməkdir.
Kamera şəkilləri kimi böyük ikili məlumatların ötürülməsi üçün Flutter MethodChannel vasitəsilə hər çağırışda buferin tam surətini çıxarmamaq üçün Uint8List ilə BasicMessageChannel istifadə etməyi tövsiyə edir.
| Dart növü | Kotlin növü | Swift növü |
|---|---|---|
| null | null | nil |
| bool | Boolean | NSNumber |
| int | Int | NSNumber |
| double | Double | NSNumber |
| String | String | NSString |
| Uint8List | ByteArray | FlutterStandardTypedData |
| List | List | Array |
| Map | HashMap | Dictionary |
Android tərəfində Method Channel-ın qurulumu FlutterPlugin tətbiq edən sinifdə və ya birbaşa MainActivity-də aparılır. Birinci yanaşma tövsiyə olunur, çünki bu, plaginin həyat dövrünün düzgün idarə edilməsini və add-to-app ssenariləri ilə uyğunluğu təmin edir.
Dart tərəfində olduğu kimi eyni ada malik kanal nörnəsi yaradıldıqdan sonra setMethodCallHandler vasitəsilə MethodCallHandler qeydiyyatdan keçirilməlidir. Handler daxilində proqramçı daxil olan metodun adını when vasitəsilə yoxlayır və nəticəni result.success və ya kod və mesajla result.error vasitəsilə qaytarır.
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()
}
}
}
}
Bu nümunədə samples.flutter.dev/battery adlı kanal getBatteryLevel çağırışını emal edir, Android BatteryManager vasitəsilə batareya səviyyəsini alır və onu Dart koduna qaytarır. Kanalın adı hər iki tərəfdə eyni olmalıdır, əks halda mesaj handlerə çatmayacaq.
Istehsalat kodu üçün Method Channel məntiqini FlutterPlugin tətbiq edən ayrıca sinfə ayırmaq tövsiyə olunur. Bu, plaginin layihələr arasında təkrar istifadəsinə imkan verir və onDetachedFromEngine çağırılarkın resursların düzgün təmizlənməsini təmin edir. Plagin registerWith vasitəsilə qeydiyyatdan keçirilir və Activity-dən təcrid olunmuş şəkildə sınaqdan keçirilə bilər.
iOS-də Method Channel FlutterPlugin protokolunu tətbiq edən sinifdə və ya AppDelegate-də qurulur. Tövsiyə olunan üsul FlutterPluginRegistrar vasitəsilə qeydiyyatdan keçən və Flutter Engine tərəfindən idarə olunan ayrıca plagin sinfi yaratmaqdır.
Dart tərəfi çağırış göndərir, native handler metodun adı və arqumentləri ilə FlutterMethodCall obyektini alır. Proqramçı çağırılan metodu call.method üzrə switch vasitəsilə müyyənləşdirir və nəticəni result bağlantısı vasitəsilə qaytarır. iOS API-yə daxil olmaq üçün UIKit və digər sistem frameworkləri istifadə olunur.
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 yanaşması Flutter Engine məhv olduqda plaginin düzgün qeydiyyatını və söndürülməsini təmin edir. Swift handlerində call.method üzrə switch istifadə olunur, hər bir case nəticəni result bağlantısı vasitəsilə qaytarır. Arqumentlər call.arguments vasitəsilə müvafiq növə çevrilməklə əldə edilir.
Method Channel ilə işlərkən proqramın performansını və sabitliyini təmin etmək üçün bir neçə əsas qaydaya riayət etmək vacibdir. Əsas tövsiyə xüsusilə animasiya dövrlərində və ya yüksək tezlikdə çağırışlarda ötürülən məlumatların miqdarını və həcmini minimallaşdırmaqdır.
Native tərəfdə həmişə istisnaları idarə etməli və insan tərəfindən oxuna bilən mesajla result.error vasitəsilə xətanı qaytarmalısınız. Dart tərəfində hər bir invokeMethod çağırışı PlatformException-ı tutmaq üçün try-catch ilə əhatə olunmalıdır. Xətaları görməmək proqramın gözlənilməz şəkildə açıq səbəb olmadan çökməsinə səbəb ola bilər.
Standart olaraq Method Channel native kodu platformanın əsas axınında yerinə yetirir. Handler ağır əməliyyat yerinə yetirirsə, icranı Android-də Kotlin Coroutines və ya iOS-də Grand Central Dispatch vasitəsilə fon axınına köçürmək lazımdır. Nəticə result vasitəsilə yalnız əsas axında iş başa çatdıqdan sonra qaytarılmalıdır.
Kanallar üçün tərs domen notasiyasından istifadə edərək unikal adlar seçin — məsələn, com.example.app/feature. Qısa adlar digər plaginlərlə ziddiyyət yarada bilər. Flutter kanalları qlobal olaraq qeydiyyatdan keçirir, buna görə müxtəlif plaginlərdə eyni adlar handlerin üstərinə yazılmasına və çağırışların işləməməsinə səbəb olur.
Tez-tez verilən suallar
MethodChannel MethodCodec vasitəsilə kodlaşdırma ilə çağırış-cavab sxemi üzrə metodları çağırmaq üçün nəzərdə tutulmuşdur. BasicMessageChannel metod və arqument formatı olmadan ixtiyari mesajları ötürür, bu da axın məlumatları və platforma hadisələri üçün əlverişlidir.
Birbaşa — yox. StandardMessageCodec yalnız əsas növləri dəstəkləyir: primitivlər, String, Uint8List, List və Map. Fərdi obyektlər göndərmədən əvvəl əl ilə Map-ə serializasiya edilməli və qəbul edən tərəfdə sahə lüğətindən bərpa edilməlidir.
Native tərəfdə xəta kodu və mesajı ilə result.error istifadə edin. Dart tərəfində invokeMethod-ı try-catch ilə əhatələyin və PlatformException tutun. Metod platformada tətbiq edilməyibsə, result.notImplemented qaytarın.
Hər çağırış izolyatlar və platformalar arasında məlumatların serializasiyasını və surətinin çıxarılmasını yerinə yetirir. Nadir çağırışlar üçün əlavə yükləmə əhəmiyyətsizdir. Kadr başına meqabayt məlumat ötürülərkən ləngimələr və FPS düşüşü mümkündür. Axın məlumatları üçün platforma görünüşlərindən və ya tekstur render obyektlərindən istifadə edin.
EventChannel istifadə edin — o, native tərəfdən Dart-a hadisələrin axın ötürülməsi üçün nəzərdə tutulmuşdur. Platforma EventSink vasitəsilə göndərməni başladır, Dart isə receiveBroadcastStream ilə axına abunə olur. Method Channel bu ssenari üçün uyğun deyil.
Yekun
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.