Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.IllegalStateException: Reply already submitted -- When trying to call result.success multiple times?

When I am trying to pass value multiple times from android native to flutter am getting the below exception.

E/AndroidRuntime(14203): java.lang.IllegalStateException: Reply already submitted
E/AndroidRuntime(14203): at io.flutter.view.FlutterNativeView$1.reply(FlutterNativeView.java:162)
E/AndroidRuntime(14203): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:194)
E/AndroidRuntime(14203): at com.dooboolab.flutterinapppurchase.FlutterInappPurchasePlugin$2.onBillingSetupFinished(FlutterInappPurchasePlugin.java:94)
E/AndroidRuntime(14203): at com.android.billingclient.api.BillingClientImpl$BillingServiceConnection.onServiceConnected(BillingClientImpl.java:903)
E/AndroidRuntime(14203): at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1386)
E/AndroidRuntime(14203): at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1403)
E/AndroidRuntime(14203): at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime(14203): at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime(14203): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime(14203): at android.app.ActivityThread.main(ActivityThread.java:5422)
E/AndroidRuntime(14203): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(14203): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime(14203): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)
E/AndroidRuntime(14203): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)

My Flutter version:

[✓] Flutter (Channel stable, 1.22.5, on Mac OS X 10.14.6 18G6032 darwin-x64, locale en-IN)

my question is how to call result.success from android native to flutter?

like image 923
M.Yogeshwaran Avatar asked Jan 29 '26 21:01

M.Yogeshwaran


2 Answers

result.success can only be called once. The simplest way to send multiple data from native to dart is to reverse the process.

  • In dart, setup the method call handler via setMethodCallHandler.
  • In Android, call invokeMethod.

Sample:

Dart code

import 'package:flutter/services.dart';

class TestChannel {
  TestChannel._() {
    _platform.setMethodCallHandler(_fromNative);
  }

  static const _platform = const MethodChannel('samples.flutter.dev/test');

  static TestChannel _instance;

  static get instance => _instance ??= TestChannel._();

  Future<bool> callTest() async {
    bool res = false;
    
    try {
      res = await _platform.invokeMethod('myMethod') == 1;
    } on PlatformException catch (e) {
      print('Error = $e');
    }

    print('Is call successful? $res');
    return res;
  }

  Future<void> _fromNative(MethodCall call) async {
    if (call.method == 'callTestResuls') {
      print('callTest result = ${call.arguments}');
    }
  }
}

Native code

package com.example.sample_app

import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {

    private val CHANNEL = "samples.flutter.dev/test"

    private lateinit var methodChannel: MethodChannel

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
        methodChannel.setMethodCallHandler {
            call, result ->
            if (call.method == "myMethod") {
                result.success(1)
                generateResults()
            }
        }
    }

    private fun generateResults() {
        for (i in 1..10) {
            methodChannel.invokeMethod("callTestResuls", i)
        }
    }

}
like image 99
rickimaru Avatar answered Jan 31 '26 10:01

rickimaru


flutter plugin code


  static Future<String?> get IpAddress_Wifi_tetherorwifi async {
final String? version =
    await _channel.invokeMethod('Wifi_tetherorWifi', {'key': 'true'});
return version;

}

Android kotlin

    methodChannel.setMethodCallHandler {
            call, result ->  if(call.method="SetHotspotEnable") enableDevice.SetHotspotEnable(object :
                EnableDevice.Ihotspot {
                override fun onEnableHotspot(hospot: Pigeon.Hotspot) {
//-------------------> this condition solve the problem
                    if (call.hasArgument("key"))
                        result.success(hospot.toMap());
                }

            })}

Here i am using a callback function so .i am usnig methodchannel not eventchannel.so after success result (may be first time success or error) when ever any second callback i got this error.so what i did that.for this solution i add argument check the argument in the callback.it works . Another method is declare local flag and check

like image 28
lava Avatar answered Jan 31 '26 11:01

lava