Service connection leaked with a custom TTS engine

178 Views Asked by At

I am using CMU Flite TTS engine for my android application. I have initialized android TTS object using engine name and also calle its shupdown method in onDestroy but still I'm getting Service connection leaked error.

03-29 15:15:37.286 21406-21406/com.example.admin.rnew E/ActivityThread: Activity com.example.admin.rnew.MainActivity has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@dc017d2 that was originally bound here
        android.app.ServiceConnectionLeaked: Activity com.example.admin.rnew.MainActivity has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@dc017d2 that was originally bound here
            at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1102)
            at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:996)
            at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1313)
            at android.app.ContextImpl.bindService(ContextImpl.java:1296)
            at android.content.ContextWrapper.bindService(ContextWrapper.java:614)
            at android.speech.tts.TextToSpeech.connectToEngine(TextToSpeech.java:800)
            at android.speech.tts.TextToSpeech.initTts(TextToSpeech.java:751)
            at android.speech.tts.TextToSpeech.<init>(TextToSpeech.java:723)
            at android.speech.tts.TextToSpeech.<init>(TextToSpeech.java:702)
            at com.example.admin.rnew.MainActivity.onCreate(MainActivity.java:119)
            at android.app.Activity.performCreate(Activity.java:6357)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2408)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2515)
            at android.app.ActivityThread.access$1000(ActivityThread.java:154)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1379)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:157)
            at android.app.ActivityThread.main(ActivityThread.java:5571)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:635)

Please anybody tell me where I am wrong. here is my code

protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    mProgressDialog = new ProgressDialog(this);
    mMediaPlayer = new MediaPlayer();
    mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    mProgressDialog.setMessage("Please wait ...");

    usertext = (EditText) findViewById(R.id.editText);
    play = (Button) findViewById(R.id.button);
    voiceempty = engine.initialize_engine(getApplicationContext());
    Toast.makeText(this,"Engine initialized",Toast.LENGTH_SHORT).show();
    if (voiceempty) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("Flite voices not installed. Please add voices in order to run the application");
        builder.setNegativeButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
                Intent intent = new Intent(Intent.ACTION_MAIN);
                intent.setComponent(new ComponentName("edu.cmu.cs.speech.tts.flite", "edu.cmu.cs.speech.tts.flite.DownloadVoiceData"));
                startActivity(intent);
                finish();
            }
        });
        AlertDialog alert = builder.create();
        alert.show();
    } else {
        // Initialize the TTS
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            mTts = new TextToSpeech(this, this, "edu.cmu.cs.speech.tts.flite");
        } else {
            mTts = new TextToSpeech(this, this);
        }
    }
}

and code for onDestroy method is

@Override
public void onDestroy()
{
    super.onDestroy();
    mTts.stop();
    mTts.shutdown();
    mMediaPlayer.stop();
    mMediaPlayer.release();
    String fileName = Environment.getExternalStorageDirectory().getAbsolutePath() + FILENAME;
    File file = new File(fileName);
    if(file.exists())
    {
        file.delete();
        Log.d("File_delete",fileName+" file deleted successfully");
    }
}

I even tried this in onBackPressed method but still getting the same error.

1

There are 1 best solutions below

0
On

My guess it that you are closing / stopping the app too quickly, before the TTS system has time to load. Try waiting a little while before pressing the back button and see if the error still happens.

I have that very same problem too. As far as I know, there is no way around it. But it doesn't have any consequences, so I chose to ignore it.

Let me know if you find a good solution though.

Also, as a side note, you should:

tts = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS){
            int langResult = copilot.setLanguage(language);

            if (langResult == TextToSpeech.LANG_MISSING_DATA
                || langResult == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.e(TAG, "ERROR: Text to speech language is not supported");

            } else {

            // code here

            Log.w(TAG, "...Text to Speech ready!");
            }

        }else{
            Log.e(TAG, "ERROR: Text to Speech initialization failed");
        }
    }
});