如何处理Flutter插件中Android TextToSpeech的DeadObjectException
问题
我开发的Flutter应用里,负责Android端文本转语音(TextToSpeech)功能的自定义插件出现崩溃:应用运行约30分钟后抛出以下异常:
android.os.DeadObjectException at android.os.BinderProxy.transactNative(Native Method) at android.os.BinderProxy.transact(BinderProxy.java:571) at android.speech.tts.ITextToSpeechService$Stub$Proxy.isLanguageAvailable(ITextToSpeechService.java:919) at android.speech.tts.TextToSpeech.lambda$isLanguageAvailable$16(TextToSpeech.java:1842) at android.speech.tts.TextToSpeech$$ExternalSyntheticLambda11.run(Unknown Source:2) at android.speech.tts.TextToSpeech$Connection.runAction(TextToSpeech.java:2361) at android.speech.tts.TextToSpeech.runAction(TextToSpeech.java:813) at android.speech.tts.TextToSpeech.runAction(TextToSpeech.java:803) at android.speech.tts.TextToSpeech.isLanguageAvailable(TextToSpeech.java:1825) at com.custom.my_audio_plugin.helpers.VoiceAssistant.isLanguageAvailable(VoiceAssistant.java:177) at com.custom.my_audio_plugin.MyAudioMapper.isLanguageAvailable(MyAudioMapper.java:358) at com.custom.my_audio_plugin.AudioMapperPlugin.onMethodCall(AudioMapperPlugin.java:150) at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:258) at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295) at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:322) at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$2j2MERcK825A5j1fv5sZ7xB2Iuo.run(Unknown Source:12) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
已确认TtsEngine初始化正常,TextToSpeech.OnInitListener回调返回TextToSpeech.SUCCESS,且崩溃期间未调用ActivityAware.onDetachedFromActivity()与FlutterPlugin.onDetachedFromEngine()方法。崩溃后出现以下日志:
I/TextToSpeech(19748): Sucessfully bound to com.google.android.tts I/TextToSpeech(19748): Connected to TTS engine I/TextToSpeech(19748): Setting up the connection to TTS engine...
解决/处理指导
- 捕获异常并重建TTS实例:在调用
isLanguageAvailable等TTS方法时,直接捕获DeadObjectException,一旦触发,立即销毁当前TextToSpeech实例并重新初始化。系统崩溃后已尝试重新绑定TTS引擎,但插件未主动处理实例重建,导致调用失效的Binder代理崩溃。 - 添加连接状态监听:注册
TextToSpeech.OnConnectionListener,监听onConnectionSuspended和onConnectionFailed回调。当连接挂起或失败时,主动触发TTS实例重建,不要等到崩溃发生再处理。 - 优化实例生命周期管理:即使未收到页面或引擎解绑回调,Android系统可能因内存回收、TTS服务重启导致Binder连接失效。可以在每次调用TTS方法前验证实例状态,或定期通过轻量方法(如
getDefaultVoice())检查有效性,捕获异常后重建实例。 - 缓存语言可用性结果:如果插件频繁调用
isLanguageAvailable,会增加TTS服务的依赖调用,加速连接异常。可以缓存首次查询的语言支持结果,无需每次都调用系统API。 - 备选TTS引擎支持:崩溃日志显示使用的是
com.google.android.tts,部分设备上该服务可能因后台清理或版本问题重启。可以添加系统内置TTS引擎(如com.android.tts)作为备选,当默认引擎连接失效时自动切换。
内容的提问来源于stack exchange,提问作者Shahbaz Hashmi
相关产品推荐
相关产品推荐

