Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android crash : Fatal Exception: java.lang.IllegalStateException Reply already submitted #375

Open
Tom3652 opened this issue Dec 7, 2024 · 10 comments
Labels
in triage The issue is being triaged

Comments

@Tom3652
Copy link

Tom3652 commented Dec 7, 2024

Describe the bug

Thanks for the package !
I have multiple crashes from my live app affecting my Android users.

Here is the StackTrace :

Fatal Exception: java.lang.IllegalStateException: Reply already submitted
       at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:431)
       at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.error(MethodChannel.java:277)
       at com.simform.audio_waveforms.WaveformExtractor$startDecode$1$1.onError(WaveformExtractor.kt:109)
       at android.media.MediaCodec$EventHandler.handleCallback(MediaCodec.java:1950)
       at android.media.MediaCodec$EventHandler.handleMessage(MediaCodec.java:1841)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:230)
       at android.os.Looper.loop(Looper.java:319)
       at android.app.ActivityThread.main(ActivityThread.java:8893)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)

To Reproduce
Unfortunately it never happened during the debug neither of the internal testing of the app so i have no clue on how to reproduce it...

Expected behavior
I would like the app to not crash.

Smartphone (please complete the following information):

  • Devices: Galaxy A13, Galaxy A12, Galaxy M12, Realme C21-Y, Galaxy A71, Realme C15
  • OS: 14, 11, 13, 11, 13, 11

Screenshots

Additional context

@jay-simformsolutions
Copy link
Collaborator

Hi @Tom3652, Thanks for filling the issue.

Can you please send me reproducible steps or audio files? Also, please share your flutter—v console output.

@Tom3652
Copy link
Author

Tom3652 commented Dec 8, 2024

Hey @jay-simformsolutions

Thanks for the quick reply, however as i said it happens on my live app and on Android devices, i have no ways to reproduce it unfortunately 😐

I was hoping you would know what is the "reply already submitted" error...

@Tom3652
Copy link
Author

Tom3652 commented Dec 8, 2024

I am adding the Redmi Note 12 5G under Android 12 as a new phone crashing today.

@jay-simformsolutions
Copy link
Collaborator

@Tom3652, We will investigate this issue and try to solve it as soon as possible.

@jay-simformsolutions jay-simformsolutions added the in triage The issue is being triaged label Dec 9, 2024
@himanshuGandhiSimform
Copy link
Collaborator

Hello @Tom3652, I just want to know if you are using the stopAllPlayer method in your app to stop all active players together.

@Tom3652
Copy link
Author

Tom3652 commented Dec 9, 2024

Hello both of you, thank you very much for your interest and answers.

I am actually not using stopAllPlayers, please see all the different methods i am calling together :

  final PlayerController controller = PlayerController();

  try {
      await controller.preparePlayer(path: audioFile);
      controller.setFinishMode(finishMode: FinishMode.stop);
      await controller.startPlayer();
    } catch (e) {
     print("error playing audio file : $e");
    }
    
  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

In Another class :

  final PlayerController controller = PlayerController();
  StreamSubscription<PlayerState>? playerStateSubscription;
  AnimationController? playAnimator;
  
   double waveWidth = 0;
   String filePath = "value";

  Future<void> init() async {
    waveWidth = widget.width - 60;

    if (mounted) {
    
        playAnimator = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 250));

      print("File path : $filePath");
      await controller.preparePlayer(
          path: filePath,
          shouldExtractWaveform: true,
          noOfSamples: _playerWaveStyle.getSamplesForWidth(waveWidth));

      playerStateSubscription = controller.onPlayerStateChanged.listen((state) {
        if (mounted) {
          stateNotifier.value = state;
          if (state == PlayerState.paused && mounted) {
            playAnimator?.reverse();
          }
        }
      });

      durationListener = controller.onCurrentDurationChanged.listen((millis) {
        positionNotifier.value =
            getAudioDuration(Duration(milliseconds: millis));
      });

      int waiting = Platform.isAndroid ? 1000 : 0;
      // On Android
      Future.delayed(Duration(milliseconds: waiting)).then((value) async {
        int millis = await controller.getDuration(DurationType.max);

        positionNotifier.value =
            getAudioDuration(Duration(milliseconds: millis));
        print(
            "Duration for file $filePath : ${positionNotifier.value}");
      });

      stopListener = AudioPlayerManager.instance.onStopPlayerListener.stream
          .listen((audioFile) async {
        if (controller.playerState.isPaused && mounted) {
          playAnimator?.reverse();
        }
        if (audioFile != filePath &&
            (controller.playerState.isPlaying ||
                controller.playerState.isPaused) &&
            mounted) {
          await controller.pausePlayer();
        }
      });
      if (mounted) {
        setState(() {});
      }
    }
  }

  @override
  void initState() {
    init();
    super.initState();
  }

  @override
  void dispose() {
    controller.dispose();
    playerStateSubscription?.cancel();
    durationListener?.cancel();
    stopListener?.cancel();
    playAnimator?.dispose();
    super.dispose();
  }

 Future<void> onTap() async {
    if (filePath.isNotEmpty) {
      HapticFeedback.mediumImpact();
      controller.playerState.isPlaying ? pause() : play();
    }
  }

  Future<void> pause() async {
    await controller.pausePlayer();
    playAnimator!.reverse();
  }

  Future<void> play() async {
    AudioPlayerManager.instance.onStopPlayerListener.add(filePath);
    controller.setFinishMode(finishMode: FinishMode.pause);
    await controller.startPlayer();
    playAnimator!.forward();
  }

Now i wonder if the error is to not await the controller.setFinishMode(finishMode: FinishMode.pause); call before startPlayer and / or the order of disposing objects ?

Thanks a lot for your help

@Tom3652
Copy link
Author

Tom3652 commented Dec 9, 2024

Hi both of you, i have got a new crash today that is on the preparePlayer. This is a variant of this bug probably :

Fatal Exception: java.lang.IllegalStateException: Reply already submitted
       at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:431)
       at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.error(MethodChannel.java:277)
       at com.simform.audio_waveforms.AudioPlayer$preparePlayer$2.onPlayerError(AudioPlayer.kt:48)
       at com.google.android.exoplayer2.ExoPlayerImpl.lambda$updatePlaybackInfo$16(ExoPlayerImpl.java:1878)
       at com.google.android.exoplayer2.util.ListenerSet$ListenerHolder.invoke(ListenerSet.java:281)
       at com.google.android.exoplayer2.util.ListenerSet.lambda$queueEvent$0(ListenerSet.java:190)
       at com.google.android.exoplayer2.util.ListenerSet.flushEvents(ListenerSet.java:211)
       at com.google.android.exoplayer2.ExoPlayerImpl.updatePlaybackInfo(ExoPlayerImpl.java:1947)
       at com.google.android.exoplayer2.ExoPlayerImpl.handlePlaybackInfo(ExoPlayerImpl.java:1774)
       at com.google.android.exoplayer2.ExoPlayerImpl.lambda$new$1(ExoPlayerImpl.java:306)
       at android.os.Handler.handleCallback(Handler.java:958)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loopOnce(Looper.java:230)
       at android.os.Looper.loop(Looper.java:319)
       at android.app.ActivityThread.main(ActivityThread.java:8919)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)

@jay-simformsolutions
Copy link
Collaborator

@Tom3652, Thanks for providing the information. We are working on this issue and will update you once we find a solution.

@Tom3652
Copy link
Author

Tom3652 commented Dec 10, 2024

Hi @jay-simformsolutions thank you very much i really apreciate it.

@Tom3652
Copy link
Author

Tom3652 commented Dec 12, 2024

I simply add the proportion here :

  • 24 crashes for com.simform.audio_waveforms.WaveformExtractor$startDecode$1$1.onError(WaveformExtractor.kt:109)
  • 8 crashes for com.simform.audio_waveforms.AudioPlayer$preparePlayer$2.onPlayerError(AudioPlayer.kt:48)

And so far no other methods are revealing this issue 🙏 and no crashes at all on iOS !

Note : i don't add the new impacted phones since it's probably not device-specific / android-version-specific, but if i will provide all the info i can give if you need it of course

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in triage The issue is being triaged
Projects
None yet
Development

No branches or pull requests

3 participants