Search code examples
flutterflutter-channelevent-channel

How to add several listener to Flutter.EventChannel?


I'm building a Flutter-Plugin which offers several UI-Widgets to interact with a native (Android/iOS) library. Updates and/or state changes of the library to the Flutter side are delegated with Events, which are delegated to Flutter over the Flutter EventChannel.

This works fine, however I want to add several listeners to the same channel. But every time I want to register a second listener, the first one gets canceled (StreamHandler.onCancel() called).

private var channel01:EventChannel.EventSink ?= null
private var channel02:EventChannel.EventSink ?= null
//...
private var channel06:EventChannel.EventSink ?= null

//One EventChannel for every UI-Widget?!?!
EventChannel(registrar.messenger(), EVENT_CHANNEL_MAIN_SCREEN, JSONMethodCodec.INSTANCE).setStreamHandler(object : EventChannel.StreamHandler {
   override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
       L.d("Listener attached for channel 01")
       postEvent(MyEvent("Send some data on attach"))
       channel01 = events
    }

    override fun onCancel(p0: Any?) {
       L.d("Listener detached for channel 01")
       channel01 = null
     }
})

//Trigger some data via flutter stream from Android/iOS to Flutter
fun postEvent(event: MyEvent) {
    activity.runOnUiThread {
        channel01?.success(event)
        channel02?.success(event) 
    }
}

So currently I'm using one EventChannel for every UI-Widget, but I guess there are better ways?

By the way, I used an Inherited Widget as a DataProvider in Flutter, which was the only listener to the EventChannel and was delegating the changes down the tree, however this is not possible due to "architecture guidelines"

Question

  • Can I add several listeners to one EventChannel?
  • Can I monitor which listeners are added or removed?!

Solution

  • It is not possible to attach several listeners to one channel.

    Suitable solution: Attach the EventChannel in one (Inherited-)Widget, lift this widget up in the tree and use flutter setState logic to update your widgets.