Platform Channels
เมื่อ Dart อย่างเดียวไม่พอ
หัวข้อที่มีชื่อว่า “เมื่อ Dart อย่างเดียวไม่พอ”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 MethodChannel: เรียก native method
หัวข้อที่มีชื่อว่า “MethodChannel: เรียก native method”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 จริง
EventChannel: stream ของ native event
หัวข้อที่มีชื่อว่า “EventChannel: stream ของ native event”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));}plugin เทียบกับ raw channel
หัวข้อที่มีชื่อว่า “plugin เทียบกับ raw channel”คุณแทบไม่ต้องเขียน channel code ด้วยมือ plugin คือ package ที่ห่อ platform channel บวกกับ native implementation ไว้หลัง Dart API ที่สะอาด — battery_plus, geolocator, camera ให้หยิบ plugin ที่ดูแลดีมาใช้ก่อน แล้วค่อยเขียน raw channel เฉพาะสิ่งที่ specific กับแอปคุณเท่านั้น
การ declare asset
หัวข้อที่มีชื่อว่า “การ declare asset”ไม่ใช่เรื่อง 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');