Ahmed
Ahmed

Reputation: 15039

Android TextToSpeech app null pointer exception

I am getting a null pointer exception report in the android developer console. I need some advise as to what possibly is the problem here, the stack trace is like this

java.lang.NullPointerException
at com.myfreeapp.workers.Speaker.onInit(Speaker.java:57)
at android.speech.tts.TextToSpeech$1.onServiceConnected(TextToSpeech.java:451)
at android.app.ActivityThread$PackageInfo$ServiceDispatcher.doConnected(ActivityThread.java:1247)
at android.app.ActivityThread$PackageInfo$ServiceDispatcher$RunConnection.run(ActivityThread.java:1264)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4668)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
at dalvik.system.NativeStart.main(Native Method)

The relevant code snippet in my app is

public Speaker(final Context context, final Settings settings) 
{   
    this.settings = settings;
    params = new HashMap<String, String>();      
    params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_ALARM));
    params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "myfreeapps");

    tts= new TextToSpeech(context, this);   
    Utils.log(TAG, "Created TextToSpeech..");
}

@Override
public void onInit(final int status) 
{
    Utils.log(TAG, "TTS onInit..");

//below is line 57 mentioned in the stack trace
    tts.setOnUtteranceCompletedListener(new SpeechFinishedListener());
    tts.setLanguage(Locale.getDefault());
    tts.setSpeechRate(settings.getSpeed());
    tts.setPitch(settings.getPitch());      
    ready = true;

}

Please first of all I need to be clear what exactly is null.. Is the stack trace pointing to variable tts on line 57 to be null..?

Or is the null pointer exception happening inside the TextToSpeech method setOnUtteranceCompletedListener ?

The Speaker instance is created on the main thread in a sticky service, and when I debug my code the callback from TextToSpeech also comes back on the same thread..

I don't understand how could the variable tts be null ???

By the way this problem is not reproducible on my end. I have this stack strace reported several times on the developer console.

Please advise,

Upvotes: 0

Views: 1900

Answers (4)

Ahmed
Ahmed

Reputation: 15039

I resolved the problem, here is how it worked

There was a case where I was creating Speaker object on a non-ui thread. The callback to onInit() would come on UI thread/main thread..

now even though running it might not always crash but I realised it was not safe and chances of null pointer exceptions are there..

so my updated code looks like this

public Speaker(final Context context, final Settings settings) 
{   
    this.settings = settings;
    params = new HashMap<String, String>();      
    params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_ALARM));
    params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "myfreeapps");

    synchronize(synchobject)
    {
       tts= new TextToSpeech(context, this);   
    }
    Utils.log(TAG, "Created TextToSpeech..");
}

@Override
public void onInit(final int status) 
{
    Utils.log(TAG, "TTS onInit..");

    synchronize(synchobject)
    {

    tts.setOnUtteranceCompletedListener(new SpeechFinishedListener());
    tts.setLanguage(Locale.getDefault());
    tts.setSpeechRate(settings.getSpeed());
    tts.setPitch(settings.getPitch());      
    ready = true;
    }

}

This seems to have resolve my problem , thanks every one for your contribution to help me out,..

Upvotes: 1

gregm
gregm

Reputation: 12159

Your code should work, but I'd try this to see if it fixes the problem:

at the top of your code put this:

Handler handler = new Handler()

then make your other code have this:

handler.post(new Runnable()
    {
        @Override
        public void run()
        {
            tts.setOnUtteranceCompletedListener(new SpeechFinishedListener());
            tts.setLanguage(Locale.getDefault());
            tts.setSpeechRate(settings.getSpeed());
            tts.setPitch(settings.getPitch());                    
        }
    });

Upvotes: 2

AnthonyW
AnthonyW

Reputation: 1998

Am I correct in assuming that Speaker is a class that is being called from outside your main activity?

It seems as if the onInit method is being called before the constructor. I see you have checked for this with log tags; what was your result?

Upvotes: 0

Alexei
Alexei

Reputation: 1068

Probably, the TextToSpeech engine is not installed on the device.

Upvotes: 0

Related Questions