Ang interaksyon sa pagitan ng Dart code at native platforms ay isang pangunahing gawain sa pag-develop ng Flutter applications na nangangailangan ng access sa mga kakayahan ng device. Ayon sa Flutter Team, 2026, ang Platform Channel ay nananatiling pangunahing mekanismo para sa naturang integrasyon, na nagbibigay ng pagpapadala ng mensahe sa pagitan ng Dart at native code ng Android at iOS nang walang karagdagang native na library.
Mga Pangunahing Punto
Platform Channel ay isang teknolohiya ng Flutter na nagbibigay ng dalawang-direksyong komunikasyon sa pagitan ng Dart code ng application at native code ng Android at iOS operating system. Kung walang Platform Channel, ang Flutter application ay limitado sa mga kakayahan na ibinigay ng framework at hindi direktang makaka-access sa camera API, sensors, Bluetooth, file system, at iba pang low-level na function ng device.
Ang arkitektura ng Platform Channel ay binuo sa prinsipyo ng asynchronous na pagpapalitan ng mensahe. Ang Dart side ay nagpapadala ng request sa pamamagitan ng channel, ang native side ay nagpoproseso nito at nagbabalik ng resulta. Lahat ng mensahe ay nise-serialize sa binary format at ipinapadala sa pamamagitan ng message buffer ng Flutter Engine, na tinitiyak ang minimal na latency sa paglipat ng data sa pagitan ng execution environment.
Ang bawat Platform Channel ay kinikilala ng isang natatanging lohikal na pangalan — isang string na nagsisilbing address para sa pag-routing ng mga mensahe. Ang Dart side at native side ay dapat gumamit ng parehong pangalan ng channel upang maitatag nang tama ang komunikasyon. Sinusuportahan ng Flutter ang kahit anong dami ng channel sa isang application, at bawat channel ay gumagana nang independyente sa isa't isa.
Ayon sa opisyal na dokumentasyon ng Flutter, pinoproseso ng Platform Channel ang mga mensahe sa parehong pagkakasunod-sunod kung saan sila ipinadala, na ginagarantiyahan ang predictability ng pagkakasunod-sunod ng tawag. Ito ay kritikal sa mga scenario kung saan ang pagkakasunod-sunod ng pagproseso ay nakakaapekto sa kawastuhan ng operasyon, halimbawa sa sunod-sunod na pagsisimula ng native modules o chain ng dependent operations.
Ang mekanismo ng pagpapadala ng mensahe sa pamamagitan ng Platform Channel ay binubuo ng tatlong pangunahing layer: ang Dart side ay nagpapadala ng mensahe bilang Map o List sa pamamagitan ng invokeMethod, ang Flutter Engine ay nagse-serialize nito gamit ang StandardMethodCodec, at ang native side ay tumatanggap ng tawag sa handler nito. Ang resulta ay bumabalik sa parehong landas sa kabaligtarang direksyon.
Ang proseso ng serialization ay awtomatikong nagko-convert ng Dart data types sa katumbas sa native platforms. Mga numero, string, boolean values, listahan, at diksyunaryo ay sinusuportahan nang walang karagdagang configuration mula sa developer. Ang custom na data types ay dapat i-serialize nang manu-mano, halimbawa sa JSON string, bago ipadala sa pamamagitan ng channel.
Sa side ng Flutter Engine, ang mensahe ay pumapasok sa queue ng main thread ng native platform. Sa Android ito ay ang main thread ng application, sa iOS — ang main run loop. Nangangahulugan ito na ang matagal na operasyon sa channel handler ay bumabara sa user interface at nagdudulot ng pag-freeze. Inirerekomenda sa mga developer na magpatakbo ng mabibigat na gawain sa background threads at ibalik ang resulta nang asynchronous sa pamamagitan ng callback.
Ang performance ng Platform Channel ay sapat na mataas para sa karamihan ng mga scenario: ang oras ng pagpapadala ng isang mensahe ay mas mababa sa 1 millisecond sa modernong mga device. Para sa mga high-load na operasyon tulad ng real-time video stream processing, inirerekomenda ang paggamit ng Dart FFI o native plugins na may direktang access sa memorya ng device.
Pangunahing limitasyon ng arkitektura: Hindi sinusuportahan ng Platform Channel ang pagpapadala ng file descriptors, memory pointers, o native objects. Lahat ng data ay dapat ma-serialize sa binary format. Para sa paglipat ng malaking dami ng data na megabytes ang laki, gumamit ng temporary files na may pagpapadala ng path sa pamamagitan ng channel.
Ang Flutter ay nagbibigay ng tatlong uri ng Platform Channel, bawat isa ay para sa tiyak na scenario ng interaksyon. Ang tamang pagpili ng uri ng channel ay tumutukoy sa arkitektura ng integrasyon at kaginhawaan ng pagpapanatili ng code sa magkabilang side — Dart at native, kaya mahalagang maunawaan ang pagkakaiba sa pagitan ng MethodChannel, EventChannel at BasicMessageChannel.
MethodChannel ay ang pinakakaraniwang uri ng Platform Channel na nagpapatupad ng pattern ng remote procedure call. Nagpapadala ang Dart ng pangalan ng method at arguments, ang native side ay nagpapatakbo ng operasyon at nagbabalik ng resulta. Bawat tawag ay nagbabalik ng Future, na nagbibigay-daan sa paggamit ng async at await constructs sa Dart code para sa maginhawang asynchronous na trabaho.
Ang uri ng channel na ito ay angkop para sa request-response na operasyon: pagkuha ng battery level, pagbabasa ng sensor data, paggawa ng computations sa native side, o pag-request ng data mula sa system services. Sinusuportahan ng MethodChannel ang standard data types sa pamamagitan ng StandardMethodCodec, kabilang ang null values salamat sa Null safety support sa modernong Dart.
Sa totoong proyekto, ang MethodChannel ay ginagamit sa karamihan ng opisyal na Flutter plugins. Halimbawa, ang camera, battery at path_provider packages ay gumagana sa pamamagitan ng uri ng channel na ito, na nagbibigay ng access sa native APIs nang hindi kailangang sumulat ng sariling integration code para sa bawat platform.
EventChannel ay para sa mga scenario kung saan ang native side ay gumagawa ng tuluy-tuloy na stream ng events sa paglipas ng panahon. Ang data ay ipinapadala sa Dart sa pamamagitan ng Stream, na nagbibigay-daan sa pag-subscribe sa real-time na updates. Mga tipikal na halimbawa ng paggamit: accelerometer readings, GPS coordinates, pagbabago ng Bluetooth status, at notifications mula sa system services.
Hindi tulad ng MethodChannel, ang EventChannel ay gumagamit ng publish-subscribe model. Ang native side ay nagpapadala ng events habang nangyayari ang mga ito, nang walang explicit request mula sa Dart code. Ang subscriber sa Dart side ay tumatanggap ng bawat event sa hiwalay na elemento ng stream at maaaring mag-filter o mag-transform ng natanggap na data bago gamitin sa interface.
Kapag gumagamit ng EventChannel, kailangan ng tamang pamamahala ng mga subscription at pagkansela ng mga ito. Bawat StreamSubscription call ay dapat kanselahin pagkatapos ng trabaho sa channel upang maiwasan ang memory leak sa native side. Awtomatikong kinakansela ng Flutter platform ang stream kapag nawasak ang widget, ngunit ang explicit na pamamahala ng subscription ay nagpapataas ng reliability ng application sa pangmatagalang scenario.
BasicMessageChannel ay ang pinaka-flexible na uri ng Platform Channel, para sa arbitraryong asynchronous na pagpapalitan ng mensahe. Hindi tulad ng MethodChannel, kung saan ang bawat mensahe ay naglalaman ng method name at arguments, ang BasicMessageChannel ay nagpapadala lamang ng payload na walang built-in routing. Ang sender side ay nagpapadala ng mensahe, ang receiver side ay nagpoproseso nito at nagbabalik ng response.
Ang uri ng channel na ito ay maginhawa para sa custom na interaction protocols, kung saan ang structure ng mensahe ay maaaring dynamic na magbago depende sa estado ng application. BasicMessageChannel ay gumagamit ng StandardMessageCodec bilang default, ngunit sinusuportahan ang pagpapalit ng arbitraryong MessageCodec para sa non-standard na data serialization formats.
Sa praktika, ang BasicMessageChannel ay mas madalang gamitin kaysa MethodChannel, dahil nangangailangan ito ng manual na pagproseso ng message routing na walang built-in na naming pattern. Ito ay hindi mapapalitan sa integrasyon ng native libraries na umaasa ng tiyak na format ng mensahe, naiiba sa standard request-response pattern na ipinatupad sa MethodChannel.
Tingnan natin ang praktikal na pagpapatupad ng Platform Channel sa halimbawa ng pagkuha ng battery level ng device. Ang halimbawang ito ay nagpapakita ng buong cycle ng trabaho: deklarasyon ng MethodChannel sa Dart side, pagpapatupad ng handler sa Android at iOS, at tamang pag-handle ng error kapag hindi available ang data o kulang ang kinakailangang permissions.
Sa Dart side, gumagawa ng instance ng MethodChannel na may natatanging string channel name. Ang invokeMethod method ay nagpapadala ng request sa native side at naghihintay ng resulta bilang Future. Ang pag-handle ng error ay ginagawa sa pamamagitan ng pag-catch ng PlatformException, na ibinabalik ng native side kapag may exception sa proseso ng pagproseso ng request.
import 'package:flutter/services.dart';
class BatteryPlugin {
static const _channel = MethodChannel(
'samples.flutter.dev/battery',
);
Future<String> getBatteryLevel() async {
try {
final result = await _channel.invokeMethod<int>(
'getBatteryLevel',
);
return 'Battery level: $result%';
} on PlatformException catch (e) {
return 'Failed: ${e.message}';
}
}
}
Sa Android side, ang handler ay nirerehistro sa MainActivity sa pamamagitan ng configureFlutterEngine method. Sa loob ng setMethodCallHandler, ang pangalan ng incoming method ay sinusuri, ang native call sa BatteryManager ay ginagawa para makuha ang battery level, at ang resulta ay ibinabalik sa pamamagitan ng result object. Para sa mga method na hindi sinusuportahan ng channel, ang result.notImplemented ay tinatawag.
import android.os.BatteryManager
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)
MethodChannel(
flutterEngine.dartExecutor.binaryMessenger,
CHANNEL
).setMethodCallHandler { call, result ->
if (call.method == "getBatteryLevel") {
val level = getBatteryLevel()
if (level != -1) {
result.success(level)
} else {
result.error(
"UNAVAILABLE",
"Battery level not available",
null
)
}
} else {
result.notImplemented()
}
}
}
private fun getBatteryLevel(): Int {
val manager = getSystemService(BATTERY_SERVICE) as BatteryManager
return manager.getIntProperty(
BatteryManager.BATTERY_PROPERTY_CAPACITY
)
}
}
Sa iOS platform, ang handler ay nirerehistro sa AppDelegate class sa pamamagitan ng FlutterMethodChannel. Ang Swift code ay tumatanggap ng incoming call, uma-access sa UIDevice system API para makuha ang battery level, at ibinabalik ang resulta sa Flutter. Ang asynchronous processing na may weak self ay nagbibigay-daan sa pag-execute ng mga request nang walang risk na magkaroon ng strong reference cycle sa memorya.
import UIKit
import Flutter
@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
override func application(
application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(
name: "samples.flutter.dev/battery",
binaryMessenger: controller.binaryMessenger
)
channel.setMethodCallHandler { [weak self] call, result in
if call.method == "getBatteryLevel" {
let level = self?.getBatteryLevel() ?? -1
if level >= 0 {
result(level)
} else {
result(FlutterError(
code: "UNAVAILABLE",
message: "Battery level not available",
details: nil
))
}
} else {
result(FlutterMethodNotImplemented)
}
}
return super.application(
application: application,
didFinishLaunchingWithOptions: launchOptions
)
}
private func getBatteryLevel() -> Int {
let device = UIDevice.current
device.isBatteryMonitoringEnabled = true
return Int(device.batteryLevel * 100)
}
}
Platform Channel ay kinakailangan sa bawat kaso kapag ang Flutter application ay nangangailangan ng access sa mga kakayahan ng device na hindi ipinatupad sa standard packages. Ang developer ay dapat gumawa ng sariling channel kapag nag-i-integrate sa native SDKs para sa camera, biometrics, NFC, Bluetooth Low Energy, o kapag nagtatrabaho sa file system sa labas ng application sandbox.
Unang tipikal na scenario — paggamit ng native APIs na walang direktang access mula sa Dart. Kasama rito ang system services ng Android at iOS, hardware sensors na may non-standard na data transfer protocols, push notifications na may custom processing logic, at cryptographic operations na nangangailangan ng Hardware Security Module para sa secure na storage ng keys.
Ikalawang scenario — integrasyon ng umiiral na native code sa Flutter project. Kung ang kumpanya ay nakagawa na ng native library para sa Android o iOS, ang Platform Channel ay nagbibigay-daan sa muling paggamit nito nang hindi nagpo-port sa Dart. Pinapabilis nito ang migration ng hybrid applications sa Flutter at pinapanatili ang investment sa umiiral na native code at naipon na business logic.
Ikatlong scenario — pag-publish ng sariling Flutter plugin sa pub.dev. Lahat ng sikat na plugin ay gumagamit ng Platform Channel para magbigay ng uniform API sa Dart, na sa ilalim ay tumatawag ng native code ng bawat platform. Ito ang standard approach na inirerekomenda ng Flutter team para sa paggawa ng reusable packages na may suporta sa parehong mobile platforms.
Kapag pumipili sa pagitan ng paggawa ng sariling Platform Channel at paggamit ng handa na package mula sa pub.dev, inirerekomenda na suriin muna ang availability ng handa na solusyon. Ang camera, geolocator, shared_preferences at path_provider packages ay sumasaklaw sa karamihan ng karaniwang pangangailangan. Ang sariling Platform Channel ay makatwiran lamang kung walang angkop na package o kung kinakailangan ang malalim na customization ng native behavior na hindi ibinibigay ng umiiral na solusyon.
Mga Madalas Itanong
MethodChannel ay nagpapatupad ng request-response pattern na may isang tawag ng method at pagbabalik ng resulta sa pamamagitan ng Future. Ang EventChannel ay gumagamit ng stream model: ang native side ay nagpapadala ng events habang nangyayari, at ang Dart ay tumatanggap sa kanila sa pamamagitan ng Stream. Ang MethodChannel ay angkop para sa isang beses na operasyon na may paghihintay ng resulta, EventChannel — para sa tuluy-tuloy na data stream sa real-time.
Sinusuportahan ng Platform Channel ang basic Dart types: int, double, bool, String, List at Map. Ang mga type na ito ay awtomatikong nise-serialize sa native equivalents sa pamamagitan ng StandardMethodCodec at StandardMessageCodec nang walang partisipasyon ng developer. Para sa pagpapadala ng custom objects, kinakailangan ang manual serialization sa JSON o paggamit ng arbitraryong MessageCodec na may suporta sa non-standard na format.
Oo, sinusuportahan ng Flutter ang walang limitasyong bilang ng Platform Channel sa isang application. Bawat channel ay kinikilala ng natatanging string name na dapat magtugma sa Dart side at native platform. Maaaring gumawa ng hiwalay na channel para sa iba't ibang module: isa para sa camera, isa para sa Bluetooth, pangatlo para sa sensors — lahat sila ay gumagana nang independyente at hindi nakakaapekto sa performance ng bawat isa.
Sa Dart side, ang mga error ay hinahawakan sa pamamagitan ng PlatformException, na ibinabalik ng native side kapag may exception. Ang try-catch block ay kumukuha ng exception at nagbibigay ng access sa code, mensahe, at detalye ng error. Sa native side, ang result.error call ay nagpapadala ng error pabalik sa Dart. Available din ang result.notImplemented method para sa mga method na hindi sinusuportahan ng channel.
Oo, ang Platform Channel handler ay nag-e-execute sa main thread ng native platform. Kung ang handler ay nagpapatakbo ng matagal na operasyon — network request, pagbasa mula sa disk, o mabibigat na computation — ang user interface ay maaaring mag-freeze. Inirerekomenda na magpatakbo ng mabibigat na gawain sa background thread sa native side at tawagin ang result pagkatapos matapos. Ang Dart side ay hindi nababara dahil sa asynchronous nature ng invokeMethod.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.