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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।