Quickblox - Flutter JNI was detached from native C++

Viewed 736

I am using Quickblox for my chats in my Flutter app. Once a connection is made, the chat works fine. When the app is send to the background, I set the connection to closed as advised by Quickblox documentation. But when I reopen my app, it does not receive messages anymore in its event (QBChatEvents.RECEIVED_NEW_MESSAGE). Although the messages are sent and received in the logs but this event does not work anymore. And the logs show this exception,

Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel:

Here's the event that I subscribe to,

QB.chat.subscribeChatEvent(QBChatEvents.RECEIVED_NEW_MESSAGE,
      (data) {
         // my implementaion here
      });

I have added this implementation from their documentation.

class _SomeScreenState extends State<SomeScreen> with WidgetsBindingObserver {
  
@override
initState() {
  super.initState();
  WidgetsBinding.instance.addObserver(this);
}

@override
void dispose() {
  WidgetsBinding.instance.removeObserver(this);
  super.dispose();
}
  
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  switch (state) {
    case AppLifecycleState.resumed:
      try {
        await QB.chat.connect(userId, userPassword);
        } on PlatformException catch (e) {
        // Some error occured, look at the exception message for more details
        }
      break;
    case AppLifecycleState.paused:
      print("app in paused");
      try {
        await QB.chat.disconnect();
      } on PlatformException catch (e) {
        // Some error occured, look at the exception message for more details
        }
      break;
}

What am I doing wrong here?

1 Answers

Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: This error occurs when method channel is destroyed
when we killed the app and try to communicate the flutter from native code then this run time error occured

Solution is below: create a new method channel in background and call the flutter part with this channel. like as below

fun  createMethodChannel(): MethodChannel? {

    var backgroundMethodChannel: MethodChannel? = null;
    var engine: FlutterEngine? = null;
    if (getEngine() == null) {
        engine = FlutterEngine(mContext!!)
        // Define a DartEntrypoint
        val entrypoint: DartExecutor.DartEntrypoint =
            DartExecutor.DartEntrypoint.createDefault()
        // Execute the DartEntrypoint within the FlutterEngine.
        engine.dartExecutor.executeDartEntrypoint(entrypoint)
    } else {
        engine = getEngine();
    }

    backgroundMethodChannel = MethodChannel(engine?.dartExecutor?.binaryMessenger, "CHANNEL_NAME")
    return backgroundMethodChannel
}
 fun getEngine(): FlutterEngine? { 
    return FlutterEngineCache.getInstance().get("CHANNEL_NAME");
}
Related