检测TextToSpeech进程死亡

时间:2017-11-21 17:01:51

标签: android deadlock text-to-speech

我正在开发一款Android应用,通过在屏幕上显示消息并同时使用TextToSpeech进行阅读,让用户了解他们的进度。为了保持视觉和听觉刺激的同步,我倾听Done事件。但是,我发现在经过一段时间(通常在20到40分钟之间)之后,内存压力导致Android开始查杀进程,并最终导致语音服务死亡。在logcat中,我看到了像

这样的行
I/ActivityManager(  565): Process com.google.android.tts (pid 7546) has died

有时我可以检测到这一点,因为当我致电Speak时,它会返回OperationResult.Error。然而,偶尔它会远远地提升Start事件但随后死亡,并且从不提出任何其他事情。 logcat显示

I/TTS     (11462): @636468802271461960: Speak(...) returned Success
I/TTS     (11462): @636468802271474010: Start utterance88
I/TextToSpeech(11462): Asked to disconnect from ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
I/TextToSpeech(11462): Connected to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
I/TextToSpeech(11462): Set up connection to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}

(前两行来自我的听众,见下文)。

通过public source code for TextToSpeech查看我发现它通过活页夹检测到该过程的死亡并重新连接,但我看不到任何要通知的挂钩,我无法看到自己访问活页夹(除了使用反射来破解对私有字段的访问,这不是一个好的做法)。

当包装的语音服务重置时,是否有任何方法可以通知,或者我是否只需要添加大量的超时?

我的听众

(代码在C#中,因为我使用的是Xamarin for Android,但是如果你能阅读那些不应该成为问题的Java)。

public class TTSProgressListener : UtteranceProgressListener, IDisposable
{
    protected internal TTSProgressListener(TextToSpeechWrapper wrapper)
    {
        _TTS = wrapper ?? throw new ArgumentNullException(nameof(wrapper));
    }

    private readonly TextToSpeechWrapper _TTS;

    #region UtteranceProgressListener

    public override void OnStart(string utteranceId)
    {
        Android.Util.Log.Info("TTS", $"@{DateTime.Now.Ticks}: Start {utteranceId}");
    }

    public override void OnDone(string utteranceId)
    {
        Android.Util.Log.Debug("TTS", $"@{DateTime.Now.Ticks}: Utterance {utteranceId} finished");
        _TTS.RaiseUtteranceFinished(utteranceId);
    }

    public override void OnError(string utteranceId)
    {
        Android.Util.Log.Warn("TTS", $"@{DateTime.Now.Ticks}: Utterance {utteranceId} errored");
        // Treat as finished to avoid the situation where a missing voice can lock the entire system. (Believed to have occurred on one test tablet).
        _TTS.RaiseUtteranceFinished(utteranceId);
    }

    #endregion
}

0 个答案:

没有答案