ข้ามไปยังเนื้อหา

Platform Channels

Flutter วาด pixel ของตัวเอง แต่บางอย่างอยู่แค่ใน native OS — ระดับแบตเตอรี่, sensor เฉพาะ, platform SDK, secure enclave การจะเข้าถึงของพวกนี้ Flutter ใช้ platform channel: ท่อส่งข้อความแบบ async ที่มี type ระหว่าง Dart code กับ native (Kotlin/Java บน Android, Swift/Objective-C บน iOS)

โมเดลก็คือ async message passing แบบเดียวกับที่คุณรู้จักจาก Dart อยู่แล้ว: คุณส่งข้อความ, ฝั่ง native จัดการ แล้ว Future complete พร้อมคำตอบ ไม่มีอะไร block UI thread

flowchart LR
  dart["Dart
invokeMethod('getBattery')"] -->|message| platform["platform channel"]
  platform --> native["native code
reads battery level"]
  native -->|reply| platform
  platform -->|Future completes| dart
round-trip ของ MethodChannel

MethodChannel ตั้งชื่อท่อและให้คุณ invokeMethod บนท่อนั้น การเรียกเป็น async และ return Future พร้อมผลลัพธ์จาก native argument และผลลัพธ์เป็น type มาตรฐาน (number, string, list, map) ที่ถูก serialize ข้ามขอบเขต

const channel = MethodChannel('samples.app/battery');
Future<int> getBatteryLevel() async {
try {
final level = await channel.invokeMethod<int>('getBatteryLevel');
return level ?? -1;
} on PlatformException catch (e) {
// native side reported an error
return -1;
}
}

ฝั่ง native ลงทะเบียน handler สำหรับชื่อ channel เดียวกัน แล้ว switch บน method string เพื่อรัน platform code จริง

MethodChannel คือการเรียกหนึ่งครั้งตอบหนึ่งครั้ง ส่วน EventChannel ส่ง stream ของ event จาก native — sensor update, การเปลี่ยน connectivity, location ซึ่ง map ไปเป็น Dart Stream คุณจึง consume ได้แบบเดียวกับ stream อื่น ๆ

const events = EventChannel('samples.app/accelerometer');
Stream<AccelData> accelerometer() {
return events.receiveBroadcastStream().map((e) => AccelData.parse(e));
}

คุณแทบไม่ต้องเขียน channel code ด้วยมือ plugin คือ package ที่ห่อ platform channel บวกกับ native implementation ไว้หลัง Dart API ที่สะอาด — battery_plus, geolocator, camera ให้หยิบ plugin ที่ดูแลดีมาใช้ก่อน แล้วค่อยเขียน raw channel เฉพาะสิ่งที่ specific กับแอปคุณเท่านั้น

ไม่ใช่เรื่อง native แต่เป็นส่วนหนึ่งของโครงสร้างแอป: รูปภาพ, font และ JSON ที่คุณ bundle ต้องถูก declare ใน pubspec.yaml เพื่อให้ถูกรวมไปกับแอป

flutter:
assets:
- assets/images/logo.png
- assets/data/
fonts:
- family: Inter
fonts:
- asset: assets/fonts/Inter-Regular.ttf
// Then load them by their declared path:
Image.asset('assets/images/logo.png');
platform channel คืออะไร?
ความต่างระหว่าง MethodChannel กับ EventChannel คืออะไร?
สำหรับความต้องการทั่วไปอย่างระดับแบตเตอรี่หรือ geolocation ควรหยิบอะไรมาใช้ก่อน?
asset ที่ bundle (รูปภาพ, font) ต้องถูก declare ที่ไหน?