androidflutterkotlinflutter-method-channelevent-channel

Event channel is not working as expected between flutter and kotlin


I did a plugin in native code(Kotlin) and tried to use that in a Flutter application. I used a method channel for Flutter to native code communication and an event channel for native code to Flutter. Method channel communication is working properly, but event channel isn't.

FLUTTER:

  // will execute this in initState
  EventChannel _eventChannel = EventChannel("STREAM_CHANNEL");
  _eventChannel.receiveBroadcastStream().map((event) => {
         // some actions
      })

  // will execute this by button click (happens after widget got built)
  result =
        await MethodChannel("METHOD_CHANNEL").invokeMethod("functionToInvoke", {
          // payload
        })

KOTLIN:


class MainActivity: FlutterActivity() {

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        startEventChannel(flutterEngine)
        startMethodChannel(flutterEngine.dartExecutor.binaryMessenger)
    }



    fun startMethodChannel(@NonNull flutterEngine: FlutterEngine) {
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, 
         "METHOD_CHANNEL").setMethodCallHandler {
             call, result -> when(call.method) {
                 "functionToInvoke" -> {           
                   // some action
                }
            }
        }

    // method not called inspite of calling from configureFlutterEngine
    fun startEventChannel(messenger: BinaryMessenger) {
        eventChannel = EventChannel(messenger, "STREAM_CHANNEL");
        eventChannel.setStreamHandler(
            object : EventChannel.StreamHandler {
                override fun onListen(arguments: Any?, eventSink: EventChannel.EventSink) 
                    {
                        eventSink.success("success")
                    }
            }
        )
    }

The startEventChannel method is not even called but startMethodChannel has been called and methods are registered properly.

There is no issue with the channel names (checked both sides).

Am I missing anything?


Solution

  • Problems:

    1. Stream not listened to:

      The stream returned by _eventChannel.receiveBroadcastStream() is not being listened to. You're only mapping the stream but this callback won't be triggered until you get data in the stream.

      And from your Kotlin EventChannel code, data is not added into the stream until you listen to the event channel.

    2. Argument Mismatch:

      The startEventChannel method requires an argument of type BinaryMessenger but you're sending it flutterEngine which is of type FlutterEngine.

    Solution:

    1. Add a listener to the stream:

      Call .listen on the mapped stream from _eventChannel.receiveBroadcastStream() like shown below:

       _eventChannel.receiveBroadcastStream().map((event) {}).listen((event) {
          // some actions
       });
      
    2. Pass the right argument to startEventChannel:

      Pass the BinaryMessenger to the startEventChannel instead of the FlutterEngine.

      startEventChannel(flutterEngine.dartExecutor.binaryMessenger)