TTS错误:泄漏ServiceConnection android.speech.tts.TextToSpeech

看来你必须在onActivityResult中调用super方法

super.onActivityResult(requestCode, resultCode, data); 

当我按下我的Activity中的后退button时,我从TTS得到这个错误。 当然,这是因为我没有调用shutdown(),但是,请参阅下面的onDestroy()。 我做了一个活动扩展的抽象TTS活动类。 我在所有的子类中调用super.onDestroy()。

 12-05 18:04:05.268: ERROR/ActivityThread(30240): Activity com.mysite.myapp.ActivitySelectItGame has leaked ServiceConnection android.speech.tts.TextToSpeech$1@43e9b4a0 that was originally bound here 12-05 18:04:05.268: ERROR/ActivityThread(30240): android.app.ServiceConnectionLeaked: Activity com.mysite.myapp.ActivitySelectItGame has leaked ServiceConnection android.speech.tts.TextToSpeech$1@43e9b4a0 that was originally bound here 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.app.ActivityThread$PackageInfo$ServiceDispatcher.<init>(ActivityThread.java:1121) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.app.ActivityThread$PackageInfo.getServiceDispatcher(ActivityThread.java:1016) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.app.ContextImpl.bindService(ContextImpl.java:863) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.content.ContextWrapper.bindService(ContextWrapper.java:347) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.speech.tts.TextToSpeech.initTts(TextToSpeech.java:467) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.speech.tts.TextToSpeech.<init>(TextToSpeech.java:433) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at com.mysite.android.library.activity.ActivityTTS.onActivityResult(ActivityTTS.java:98) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at com.mysite.myapp.ActivityGame.onActivityResult(ActivityGame.java:445) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.app.Activity.dispatchActivityResult(Activity.java:3890) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.app.ActivityThread.deliverResults(ActivityThread.java:3511) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3557) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.app.ActivityThread.access$2800(ActivityThread.java:125) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2063) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.os.Handler.dispatchMessage(Handler.java:99) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.os.Looper.loop(Looper.java:123) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at android.app.ActivityThread.main(ActivityThread.java:4627) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at java.lang.reflect.Method.invokeNative(Native Method) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at java.lang.reflect.Method.invoke(Method.java:521) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 12-05 18:04:05.268: ERROR/ActivityThread(30240): at dalvik.system.NativeStart.main(Native Method) 

我的课程扩展的活动

 public abstract class ActivityTTS extends Activity implements OnInitListener { //TEXT TO SPEECH SERVICE public static final int CHECK_TTS_AVAILABILITY = 101; private static final String TAG = "ActivityTTS"; private TextToSpeech mTts; //Text to speech library //MESSAGES private String NO_TTS_ANDROID_MARKET_REDIRECT = "'SpeechSynthesis Data Installer' is not installed on your system, you are being redirected to" + " the installer package. You may also be able to install it my going to the 'Home Screen' then " + "(Menu -> Settings -> Voice Input & output -> Text-to-speech settings)"; private String NO_TTS_AVAILABLE = "'SpeechSynthesis Data Installer' is not available on your system, " + "you may have to install it manually yourself. You may also be able to install it my going to the 'Home Screen' " + "then (Menu -> Settings -> Voice Input & output -> Text-to-speech settings)"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "onCreate() called in ActivityTTS"); try { //A weird error was occurring on some phones with the TTS, hence the try catch //TTS Service Intent checkIntent = new Intent(); checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA); startActivityForResult(checkIntent, CHECK_TTS_AVAILABILITY); } catch (Exception e) { Toast.makeText(this, NO_TTS_AVAILABLE, Toast.LENGTH_LONG).show(); finish(); } } @Override protected void onStart() { super.onStart(); } @Override protected void onStop() { super.onStop(); } /** * Add a custom audio file for a particular * audio element. * * @param text * @param filename */ protected void addSpeech(String text, String filename ) { mTts.addSpeech(text, filename); } /** * For TTS */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { try { //Log.d(TAG, "TTS Response: "+requestCode); if (requestCode == CHECK_TTS_AVAILABILITY) { if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) { // success, create the TTS instance this.mTts = new TextToSpeech(this, this); } else { // missing data, install it Toast.makeText(this, NO_TTS_ANDROID_MARKET_REDIRECT, Toast.LENGTH_LONG).show(); PackageManager pm = getPackageManager(); Intent installIntent = new Intent(); installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); ResolveInfo resolveInfo = pm.resolveActivity( installIntent, PackageManager.MATCH_DEFAULT_ONLY ); if( resolveInfo == null ) { // Not able to find the activity which should be started for this intent Toast.makeText(this, NO_TTS_AVAILABLE, Toast.LENGTH_LONG).show(); } else { startActivity( installIntent ); } finish(); } } }catch (Exception e) { Log.e(TAG, "Unable to access service"); finish(); } } /** * Loads when the TTS is ready */ @Override public void onInit(int status) { mTts.setLanguage(Locale.getDefault()); } /** * Speak text */ protected void speak(String text) { try{ mTts.stop(); //Stop speaking mTts.speak(text, TextToSpeech.QUEUE_FLUSH, null); } catch(Exception e) { Log.e(TAG, "TTS Failed - cannot say: "+text ); } } /** * Speak a pre-recorded word */ protected void speak(String text, File filename) { try{ mTts.stop(); //Stop speaking mTts.addSpeech(text, filename.toString()); mTts.speak(text, TextToSpeech.QUEUE_FLUSH, null); } catch(Exception e) { Log.e(TAG, "TTS Failed - cannot say: "+text ); } } @Override protected void onDestroy() { super.onDestroy(); //Close the Text to Speech Library if(mTts != null) { mTts.stop(); mTts.shutdown(); Log.d(TAG, "TTS Destroyed"); } } public void setLanguage(Locale audioLocale) { mTts.setLanguage(audioLocale); } } 

这里是与ActivityGame中的活动相关的代码

 public abstract class ActivityGame extends ActivityTTS { ... protected void speak() { if (Logging.INFO) Log.i(TAG, "Speaking"); if(this.mVoicePreference) { String word = mBoundService.getCurrentWord().getSpelling(); if(WordRecordingHelper.recordingExists(word)) { try{ File f = new File(Constants.SDCARD_RECORDINGS+WordRecordingHelper.formatRecordedWord(word)); super.addSpeech(word, f.getAbsolutePath()); } catch (Exception e) { if(Logging.WARN) Log.w(TAG, "An error occurred while trying to use addSpeech()", e); } } //play the audio super.speak(word); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); ... } @Override protected void onDestroy() { super.onDestroy(); .... } } 

这里是ActivitySelectItGame,它根本不参考TTS,只是扩展了ActivityGame

 public class ActivitySelectItGame extends ActivityGame { ... } 

但是我从一个完全不相关的Activity中得到完全相同的问题扩展了ActivityTTS。

Solutions Collecting From Web of "TTS错误:泄漏ServiceConnection android.speech.tts.TextToSpeech"

 @Override protected void onDestroy() { //Close the Text to Speech Library if(mTts != null) { mTts.stop(); mTts.shutdown(); Log.d(TAG, "TTS Destroyed"); } super.onDestroy(); } 

我认为问题是在活动被破坏之后,你正在克服mTts。 尝试使用我发布的代码。 让我知道这是否成功

每次创buildmtts实例时,都需要shutdown它。

换句话说,如果你有多个new TextToSpeech(xxx)你需要有相同数量的shutdown()

这对我有用。

我不确定系统总是调用onDestroy()。 我已经看到它在我的模拟器中被跳过的例子。 但是我不能每次都重现这种情况。 我已经使用TTS,没有泄漏问题。 我调用onPause()中的mTts.shutdown()并在onResume()中重新初始化它。 这对我来说很好。

onCreate() ,为了检查TTS是否可用,开始结果的活动,可以被框架多次调用。 所以我想你可能会在onActivityResult()创build多个TTS实例。 有关更多信息,请参阅Activity类的图表 。 请注意,可以在调用onStop()之后再次调用onCreate() onStop()

在我的片段中使用WebView时,我得到了这个泄漏的连接。 在onCreateView方法中,我做了setJavaScriptEnabled(true),导致这个错误,当按下活动。 为了摆脱它,我将设置移动到onResume(),并在onPause()中设置为false,然后问题消失。