[{"data":1,"prerenderedAt":22},["ShallowReactive",2],{"articolo-flutter-e-le-piattaforme-scrivere-codice-nativo-con-i-platform-channels":3,"comments-article-flutter-e-le-piattaforme-scrivere-codice-nativo-con-i-platform-channels":21},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"video_url":10,"status":11,"published_at":12,"meta_title":13,"meta_description":14,"category":15,"author":19},7,"Flutter e le piattaforme: scrivere codice nativo con i Platform Channels","flutter-e-le-piattaforme-scrivere-codice-nativo-con-i-platform-channels","Scopri come integrare codice nativo Android e iOS nelle tue app Flutter usando i Platform Channels: MethodChannel, EventChannel e le nuove Pigeon per una comunicazione type-safe.","## Perché servono i Platform Channels\n\nFlutter offre un ricco set di plugin pronti all'uso, ma prima o poi capita di dover accedere a funzionalità native non ancora coperte: un SDK proprietario, un sensore particolare, API di sistema specifiche. In questi casi entrano in gioco i **Platform Channels**, il meccanismo ufficiale con cui il codice Dart comunica con il codice nativo (Kotlin\u002FJava su Android, Swift\u002FObjective-C su iOS).\n\nLa comunicazione è **asincrona** e basata sullo scambio di messaggi serializzati tramite un codec binario standard. Dart invia un messaggio, la piattaforma host lo riceve, esegue il lavoro nativo e restituisce un risultato.\n\n## I tre tipi di canale\n\n- **MethodChannel**: per invocare singoli metodi nativi e ricevere una risposta.\n- **EventChannel**: per ricevere flussi continui di dati dalla piattaforma (es. aggiornamenti di posizione, livello batteria).\n- **BasicMessageChannel**: per lo scambio di messaggi asincroni bidirezionali con un codec personalizzabile.\n\n## Esempio con MethodChannel\n\nSupponiamo di voler recuperare il livello della batteria dal lato nativo. Sul lato Dart:\n\n```dart\nimport 'package:flutter\u002Fservices.dart';\n\nclass BatteryService {\n  static const _channel = MethodChannel('it.esempio\u002Fbattery');\n\n  Future\u003Cint> getBatteryLevel() async {\n    try {\n      final level = await _channel.invokeMethod\u003Cint>('getBatteryLevel');\n      return level ?? -1;\n    } on PlatformException catch (e) {\n      print('Errore nativo: ${e.message}');\n      return -1;\n    }\n  }\n}\n```\n\nSul lato Android (Kotlin), in `MainActivity.kt`:\n\n```kotlin\nimport io.flutter.embedding.android.FlutterActivity\nimport io.flutter.embedding.engine.FlutterEngine\nimport io.flutter.plugin.common.MethodChannel\nimport android.os.BatteryManager\nimport android.content.Context\n\nclass MainActivity : FlutterActivity() {\n    private val CHANNEL = \"it.esempio\u002Fbattery\"\n\n    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {\n        super.configureFlutterEngine(flutterEngine)\n        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)\n            .setMethodCallHandler { call, result ->\n                if (call.method == \"getBatteryLevel\") {\n                    val bm = getSystemService(Context.BATTERY_SERVICE) as BatteryManager\n                    val level = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)\n                    result.success(level)\n                } else {\n                    result.notImplemented()\n                }\n            }\n    }\n}\n```\n\nÈ fondamentale che il **nome del canale** sia identico su entrambi i lati e che venga gestito il caso `notImplemented()`.\n\n## Streaming di dati con EventChannel\n\nQuando i dati arrivano nel tempo, l'`EventChannel` espone uno `Stream`:\n\n```dart\nclass SensorService {\n  static const _events = EventChannel('it.esempio\u002Fsensor');\n\n  Stream\u003Cdouble> get accelerometer =>\n      _events.receiveBroadcastStream().map((e) => e as double);\n}\n```\n\nDal lato nativo si usa un `EventChannel.StreamHandler` che invia eventi tramite `eventSink.success(...)`.\n\n## Pigeon: addio al boilerplate e ai typo\n\nScrivere manualmente la serializzazione dei dati e i nomi dei metodi è soggetto a errori. **Pigeon** è il pacchetto ufficiale di Google che genera codice type-safe per Dart, Kotlin\u002FJava e Swift\u002FObjective-C a partire da una definizione condivisa.\n\nSi definisce un'interfaccia in un file Dart:\n\n```dart\nimport 'package:pigeon\u002Fpigeon.dart';\n\nclass BatteryInfo {\n  int? level;\n  bool? isCharging;\n}\n\n@HostApi()\nabstract class BatteryApi {\n  BatteryInfo getBatteryInfo();\n}\n```\n\nPoi si lancia il generatore:\n\n```bash\ndart run pigeon \\\n  --input pigeons\u002Fbattery_api.dart \\\n  --dart_out lib\u002Fbattery_api.g.dart \\\n  --kotlin_out android\u002Fapp\u002Fsrc\u002Fmain\u002Fkotlin\u002F...\u002FBatteryApi.g.kt \\\n  --swift_out ios\u002FRunner\u002FBatteryApi.g.swift\n```\n\nPigeon crea automaticamente le classi e i metodi corrispondenti, eliminando le stringhe magiche e garantendo coerenza dei tipi a tempo di compilazione.\n\n## Best practice\n\n- **Mantieni l'API minimale**: passa solo i dati strettamente necessari attraverso il canale.\n- **Gestisci sempre gli errori** con `PlatformException` lato Dart e `result.error(...)` lato nativo.\n- **Esegui il lavoro pesante su thread in background** nel codice nativo, ma ricorda che la risposta al `result` deve avvenire sul main thread.\n- **Preferisci Pigeon** per progetti strutturati: riduce i bug e migliora la manutenibilità.\n- **Isola la logica** dietro un service Dart, così il resto dell'app non conosce i dettagli del canale.\n\n## Conclusione\n\nI Platform Channels sono il ponte che rende Flutter davvero potente quando occorre uscire dal recinto delle API multipiattaforma. Con `MethodChannel` ed `EventChannel` copri la maggior parte dei casi, mentre Pigeon porta sicurezza dei tipi e meno boilerplate. Padroneggiare questi strumenti ti permette di integrare qualsiasi funzionalità nativa senza rinunciare alla produttività di Flutter.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002Fa08dc86d-2de1-4bf9-8560-cb8af54144b8.jpg",null,"published","2026-06-10T04:00:34+00:00","Platform Channels in Flutter: guida al codice nativo","Impara a integrare codice nativo Android e iOS in Flutter con MethodChannel, EventChannel e Pigeon. Guida pratica con esempi Dart, Kotlin e best practice.",{"id":16,"name":17,"slug":18},1,"Guide","guide",{"id":16,"name":20},"Flutter Bot",[],1781247856447]