Method Channel Flutter में Dart कोड और iOS व Android के नेटिव पक्ष के बीच द्विदिश संचार की एक प्रणाली है। 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 ऑब्जेक्ट भेजता है। हैंडलर आवश्यक कोड निष्पादित करता है और परिणाम लौटाता है, जो रिवर्स क्रमांकन पथ से गुज़रता है और Future के रूप में Dart तक पहुँचता है।
Method Channel की आर्किटेक्चर कई परस्पर जुड़ी संस्थाओं से बनी है, जिनमें से प्रत्येक डेटा स्थानांतरण के अपने चरण के लिए जिम्मेदार है। Dart API MethodChannel वर्ग प्रदान करता है, जो डेवलपर से क्रमांकन और रूटिंग के निम्न-स्तरीय विवरणों को छिपाता है।
BinaryMessenger Dart और होस्ट प्लेटफ़ॉर्म के बीच बाइनरी संदेश भेजने और प्राप्त करने के लिए Flutter Engine का निम्न-स्तरीय इंटरफ़ेस है। प्रत्येक MethodChannel एक विशिष्ट BinaryMessenger से बंधता है जो चैनल नाम द्वारा रूटिंग प्रदान करता है। Dart पक्ष पर BinaryMessenger वर्ग का उपयोग किया जाता है, Android पर — io.flutter.embedding.engine पैकेज से BinaryMessenger, 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 MethodChannel के माध्यम से प्रत्येक कॉल पर पूर्ण बफ़र प्रतिलिपि से बचने के लिए Uint8List के साथ BasicMessageChannel का उपयोग करने की सलाह देता है।
| 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 |
Android पक्ष पर Method Channel की स्थापना एक ऐसी क्लास में की जाती है जो FlutterPlugin को लागू करती है, या सीधे MainActivity में। पहला दृष्टिकोण अनुशंसित है क्योंकि यह प्लगइन जीवनचक्र का उचित प्रबंधन और add-to-app परिदृश्यों के साथ संगतता सुनिश्चित करता है।
Dart पक्ष के समान नाम वाले चैनल का एक उदाहरण बनाने के बाद, setMethodCallHandler के माध्यम से MethodCallHandler पंजीकृत करना आवश्यक है। हैंडलर के अंदर, डेवलपर 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 से अलग परीक्षण किया जा सकता है।
iOS पर Method Channel को FlutterPlugin प्रोटोकॉल लागू करने वाली क्लास में या AppDelegate में सेट किया जाता है। अनुशंसित तरीका एक अलग प्लगइन क्लास बनाना है जो FlutterPluginRegistrar के माध्यम से पंजीकृत होती है और Flutter Engine द्वारा प्रबंधित की जाती है।
Dart पक्ष एक कॉल भेजता है, नेटिव हैंडलर मेथड नाम और आर्गुमेंट के साथ एक FlutterMethodCall ऑब्जेक्ट प्राप्त करता है। डेवलपर call.method पर switch के माध्यम से कॉल की गई मेथड की पहचान करता है और 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 हैंडलर में call.method पर switch का उपयोग किया जाता है, प्रत्येक केस result क्लोज़र के माध्यम से परिणाम लौटाता है। आर्गुमेंट call.arguments के माध्यम से उपयुक्त प्रकार में रूपांतरण के साथ उपलब्ध हैं।
Method Channel के साथ काम करते समय, एप्लिकेशन के प्रदर्शन और स्थिरता को सुनिश्चित करने के लिए कई प्रमुख नियमों का पालन करना महत्वपूर्ण है। मुख्य सिफारिश स्थानांतरित डेटा की मात्रा और आकार को कम करना है, विशेष रूप से एनिमेशन लूप या उच्च आवृत्ति वाले कॉल में।
नेटिव पक्ष पर हमेशा अपवादों को संभालना चाहिए और result.error के माध्यम से मानव-पठनीय संदेश के साथ त्रुटि लौटानी चाहिए। Dart पक्ष पर, PlatformException को पकड़ने के लिए प्रत्येक invokeMethod कॉल को try-catch में लपेटा जाना चाहिए। त्रुटियों को अनदेखा करने से स्पष्ट कारण के बिना अप्रत्याशित एप्लिकेशन क्रैश हो सकता है।
डिफ़ॉल्ट रूप से, Method Channel नेटिव कोड को प्लेटफ़ॉर्म के मुख्य धागे पर निष्पादित करता है। यदि हैंडलर कोई भारी कार्य करता है, तो निष्पादन को Android पर Kotlin Coroutines या iOS पर Grand Central Dispatch का उपयोग करके पृष्ठभूमि धागे पर स्थानांतरित किया जाना चाहिए। परिणाम मुख्य धागे पर कार्य पूरा होने के बाद ही 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 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।