TTS - 泄露的ServiceConnection

时间:2013-03-22 05:31:35

标签: android

我在APP中使用TTS。在onPuase方法期间,我使用以下代码来停止引擎。问题是每当我暂停活动时说使用主页按钮,我得到错误,因为我已经粘贴在日志猫部分。我从log cat(Activity com.example.DragDrop.PlaySeries泄漏了ServiceConnection)了解到这个问题是由于一些泄漏造成的。但问题不是停止我的应用程序或干扰任何功能。但我想知道这个问题的严重性以及如何避免这个问题?

请帮忙

protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();   
    Log.i("PlaySeries", "In pause play series");
    if(tts !=null){
        Log.i("PlaySeries", "In pause play series");
        tts.stop(); 
    //  tts.shutdown();
    }
}

@Override
protected void onDestroy() {  
    //Close the Text to Speech Library
    if(tts !=null){
        Log.i("PlaySeries", "In pause play series");
        tts.stop(); 
        tts.shutdown();
    }
    super.onDestroy();
}

和onCreate

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.series);

    tts = new TextToSpeech(this,this);
}

logcat的

 03-22 10:46:45.205: E/ActivityThread(3881): Activity com.example.DragDrop.PlaySeries has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@2bbe5960 that was originally bound here03-22 10:46:45.205: E/ActivityThread(3881): android.app.ServiceConnectionLeaked: Activity com.example.DragDrop.PlaySeries has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@2bbe5960 that was originally bound here03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): android.app.ServiceConnectionLeaked: Activity com.example.DragDrop.PlaySeries has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@2bbe5960 that was originally bound here03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 03-22 10:46:45.205: E/ActivityThread(3881): 
 03-22 10:46:45.205: E/ActivityThread(3881): 

3 个答案:

答案 0 :(得分:11)

只需拥有此代码onDestroy

@Override
protected void onDestroy()
{
    super.onDestroy();

    tts.shutdown();
}

答案 1 :(得分:10)

当我将TTS对象设置为静态时,我遇到了类似的错误(因此即使设备旋转,TTS也继续说话)。设备旋转时触发泄漏,因此屏幕在纵向和横向模式之间切换。

有一段时间我感到困惑,因为错误仅在运行早期版本Android的一些旧设备上报告。但是,一旦我发现了修复程序,我怀疑这个问题在所有设备和版本中都很常见,但可能会在较新的模型上屏蔽。

修复方法是使用Application Context初始化TTS对象,而不是当前(Activity)上下文。

这是我的代码  tts = new TextToSpeech(getApplicationContext(), this);

完整的差异可在以下位置获得: http://code.google.com/p/android-tts-experiments/source/detail?r=b879fd1042151cbebc736b89a9fb660c895081ea

答案 2 :(得分:1)

以下是来自活动/服务之外的TTS的TurnKey解决方案......

如果你不能使用onDestroy,只需听完讲话然后关机并停止TTS。使用应用程序上下文来防止泄漏。你走了。

    import android.content.Context;
import android.os.Build;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.util.Log;

import java.util.Locale;

/**
 * Created by acopp
 * Date: 1/11/2017.
 * Time: 6:11 AM
 * You have permission to use this file for any reason that is not for evil doing
 */

class SpeakThis{
    private Context mContext;
    private TextToSpeech mTextToSpeech;
    private String mTextToSpeak = "";
    private boolean mSpeechAvailable = false;

    SpeakThis(String text,Context context){
        mTextToSpeak = text;
        mContext = context.getApplicationContext();//THIS WILL FIX THE LEAK  THANKS TO JulianHarty

        mTextToSpeech = new TextToSpeech(mContext, mTextToSpeechListener);
        mTextToSpeech.setOnUtteranceProgressListener(mUtteranceListener);//NO ON DESTROY NEEDED JUST LISTEN FOR UTTERANCE STATUS
    }

    void talk(String talkThis){
        mTextToSpeak = talkThis;
        if(mSpeechAvailable){
            speak();
        }else{
            mTextToSpeech = new TextToSpeech(mContext, mTextToSpeechListener);
            mTextToSpeech.setOnUtteranceProgressListener(mUtteranceListener);
            mTextToSpeech.setSpeechRate(0.75f);
            mTextToSpeech.setPitch(1.2f);
        }
    }

    private TextToSpeech.OnInitListener mTextToSpeechListener = new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int status) {
            if (status == TextToSpeech.SUCCESS) {
                int result = mTextToSpeech.setLanguage(Locale.US);
                if (result == TextToSpeech.LANG_MISSING_DATA ||
                        result == TextToSpeech.LANG_NOT_SUPPORTED) {
                    Log.e("TTS","SPEECH NOT AVAILALBE");
                    mSpeechAvailable = false;

                } else {
                    if(mTextToSpeak.length() > 2){
                        speak();
                    }
                    mSpeechAvailable = true;
                }
            } else {
                Log.e("TTS", "Initilization Failed!");
                mSpeechAvailable = false;
            }

        }
    };

    private void speak() {

        if (mTextToSpeak.length() > 0) {
            try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    mTextToSpeech.speak(mTextToSpeak, TextToSpeech.QUEUE_ADD,null,"toastText");
                } else {
                    //noinspection deprecation
                    mTextToSpeech.speak(mTextToSpeak, TextToSpeech.QUEUE_ADD, null);
                }
            } catch (Exception ignore) {

            }
        }
    }

    private UtteranceProgressListener mUtteranceListener = new UtteranceProgressListener() {
        @Override
        public void onStart(String s) {
        }

        @Override
        public void onDone(String s) {//STOP AND SHUTDOWN TTS WHEN COMPLETED TALKING
            try {
                mTextToSpeech.stop();
                mTextToSpeech.shutdown();
            } catch (Exception ignore) {
            }
        }

        @Override
        public void onError(String s) {

        }
    };
}